From 31e00a6d982c4c6827ae6e57bba7e7415fc32c2a Mon Sep 17 00:00:00 2001 From: emrergin Date: Wed, 15 Mar 2023 01:09:17 +0300 Subject: [PATCH 01/24] implemented mantine --- exporting.sh | 9 + next.config.js | 1 + package-lock.json | 2040 +++++++++++++++++ package.json | 12 +- src/components/Intro.tsx | 43 +- src/components/Intro2.tsx | 220 +- src/components/Round.tsx | 8 +- .../experimentComponents/BagHolder.tsx | 33 +- .../experimentComponents/Drawing.tsx | 12 +- src/pages/_app.tsx | 47 +- src/pages/_document.tsx | 30 +- src/pages/index.tsx | 37 +- src/styles/Custom.module.css | 25 +- 13 files changed, 2354 insertions(+), 163 deletions(-) create mode 100644 exporting.sh diff --git a/exporting.sh b/exporting.sh new file mode 100644 index 0000000..9a34e38 --- /dev/null +++ b/exporting.sh @@ -0,0 +1,9 @@ +#! /bin/bash +next build +cp -r public .next/standalone +cp -r ./.next/static .next/standalone/.next +cd /media/sf_linux_erisim/ +if [ -d standalone ]; then rm -r standalone; fi +cd /home/zulmet/odin1/belief-next/.next +cp -r standalone /media/sf_linux_erisim/ + \ No newline at end of file diff --git a/next.config.js b/next.config.js index 3901244..a0a7d51 100644 --- a/next.config.js +++ b/next.config.js @@ -2,6 +2,7 @@ const nextConfig = { reactStrictMode: true, basePath: '/belief', + output: 'standalone', }; module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json index 7428949..217298d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,19 @@ "name": "belief-next", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.10.6", + "@emotion/server": "^11.10.0", + "@mantine/carousel": "^6.0.1", + "@mantine/core": "^6.0.1", + "@mantine/dates": "^6.0.1", + "@mantine/form": "^6.0.1", + "@mantine/hooks": "^6.0.1", + "@mantine/next": "^6.0.1", "@prisma/client": "^4.11.0", "@types/node": "18.14.4", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", + "dayjs": "^1.11.7", "embla-carousel-react": "^7.1.0", "eslint": "8.35.0", "eslint-config-next": "13.2.3", @@ -24,6 +33,121 @@ "prisma": "^4.11.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/runtime": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", @@ -35,6 +159,141 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.1", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.1.3" + } + }, + "node_modules/@emotion/cache": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "dependencies": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.1", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.1.3" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + }, + "node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "node_modules/@emotion/react": { + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", + "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.6", + "@emotion/cache": "^11.10.5", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "dependencies": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/server": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/@emotion/server/-/server-11.10.0.tgz", + "integrity": "sha512-MTvJ21JPo9aS02GdjFW4nhdwOi2tNNpMmAM/YED0pkxzjDNi5WbiTwXqaCnvLc2Lr8NFtjhT0az1vTJyLIHYcw==", + "dependencies": { + "@emotion/utils": "^1.2.0", + "html-tokenize": "^2.0.0", + "multipipe": "^1.0.2", + "through": "^2.3.8" + }, + "peerDependencies": { + "@emotion/css": "^11.0.0-rc.0" + }, + "peerDependenciesMeta": { + "@emotion/css": { + "optional": true + } + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + }, "node_modules/@eslint/eslintrc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", @@ -65,6 +324,45 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.4.tgz", + "integrity": "sha512-SQOeVbMwb1di+mVWWJLpsUTToKfqVNioXys011beCAhyOIFtS+GQoW4EQSneuxzmQKddExDwQ+X0hLl4lJJaSQ==" + }, + "node_modules/@floating-ui/dom": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.4.tgz", + "integrity": "sha512-4+k+BLhtWj+peCU60gp0+rHeR8+Ohqx6kjJf/lHMnJ8JD5Qj6jytcq1+SZzRwD7rvHKRhR7TDiWWddrNrfwQLg==", + "dependencies": { + "@floating-ui/core": "^1.2.3" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", + "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", + "dependencies": { + "@floating-ui/react-dom": "^1.3.0", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "dependencies": { + "@floating-ui/dom": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -95,6 +393,128 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "node_modules/@mantine/carousel": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/carousel/-/carousel-6.0.1.tgz", + "integrity": "sha512-ARwb/Ov4I7zH+3NA42YjSNnv+Tt9dX2BPsmbXaZXhwVTRi2eJZUyLQNsMh8FutlGXbrjtoWrf1DnI96v9CBkpg==", + "dependencies": { + "@mantine/utils": "6.0.1" + }, + "peerDependencies": { + "@mantine/core": "6.0.1", + "@mantine/hooks": "6.0.1", + "embla-carousel-react": "^7.0.0", + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/core": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.1.tgz", + "integrity": "sha512-RJ0gnEOMQu9qGV9bZxb4FrHe3UT2GjVokzZ91C/Ht8DTu8Ar1uUch45+VsqI67JG2ceHykOMvsDWgAulCUKBNg==", + "dependencies": { + "@floating-ui/react": "^0.19.1", + "@mantine/styles": "6.0.1", + "@mantine/utils": "6.0.1", + "@radix-ui/react-scroll-area": "1.0.2", + "react-remove-scroll": "^2.5.5", + "react-textarea-autosize": "8.3.4" + }, + "peerDependencies": { + "@mantine/hooks": "6.0.1", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/dates": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.1.tgz", + "integrity": "sha512-ZoKrlEN0YF96Jxr7bFSwZtYm+OSWdc/x8MHFaVmqsN4xkW0WFdv9WyWPLYW+GCeSrw5jcj+XC3dWEY2g/RCacw==", + "dependencies": { + "@mantine/utils": "6.0.1" + }, + "peerDependencies": { + "@mantine/core": "6.0.1", + "@mantine/hooks": "6.0.1", + "dayjs": ">=1.0.0", + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/form": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.1.tgz", + "integrity": "sha512-oRoe6YnurOzAGUY1DGXTFLofWPEeE8prEdwOv3pJEsp4ggaZAaQQSivIla5yzcsQasptOxMr2Gb8AOk4Ch/WHg==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "klona": "^2.0.5" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/hooks": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.1.tgz", + "integrity": "sha512-D3zWNPMrmjBbns0krXCE5FyWNmrKosYqD+J4/yyBrngvN6XMlmqfUr4C6ofndRrpZHxyshEJgVYLvB5h2bioGQ==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/next": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/next/-/next-6.0.1.tgz", + "integrity": "sha512-+7Mb79V+ah/XhVmOTQ6tlg0ZHZhweTgryQO9u87wD8KMxuuNhdNLZq27E8390PTXHhxFO93T7k4WbQqIXQOkUg==", + "dependencies": { + "@mantine/ssr": "6.0.1", + "@mantine/styles": "6.0.1" + }, + "peerDependencies": { + "next": "*", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/ssr": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/ssr/-/ssr-6.0.1.tgz", + "integrity": "sha512-qAQEqkVZ6uirdlZzD4ia3yW7PSxITkLjuqHMgabUbfk383xko3MAcdoUHz9cufpB8w+qJzuqUUR9D7mkJCChzQ==", + "dependencies": { + "@mantine/styles": "6.0.1", + "html-react-parser": "1.4.12" + }, + "peerDependencies": { + "@emotion/react": ">=11.9.0", + "@emotion/server": ">=11.4.0", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/styles": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.1.tgz", + "integrity": "sha512-5hY5Tt0v8GzJ4PSuE9DHlHMmzFi2Vs/l9nVc5feut0vp7GqDvoSMH+gBvsMIIsgGif+nhdztvdpv1aI0YRZgtA==", + "dependencies": { + "clsx": "1.1.1", + "csstype": "3.0.9" + }, + "peerDependencies": { + "@emotion/react": ">=11.9.0", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/styles/node_modules/csstype": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + }, + "node_modules/@mantine/utils": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.1.tgz", + "integrity": "sha512-uEN457ELHpKXS4qNAcL5OR9dFOjeFngWRZJVAPkLafWBJuLd2qmdLvKLgUVyt+cMVFtcjnu6rGVOite1+dtaFw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@next/env": { "version": "13.2.3", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.2.3.tgz", @@ -386,6 +806,137 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.11.0-57.8fde8fef4033376662cad983758335009d522acb.tgz", "integrity": "sha512-3Vd8Qq06d5xD8Ch5WauWcUUrsVPdMC6Ge8ILji8RFfyhUpqon6qSyGM0apvr1O8n8qH8cKkEFqRPsYjuz5r83g==" }, + "node_modules/@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", + "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", @@ -409,6 +960,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.4.tgz", "integrity": "sha512-VhCw7I7qO2X49+jaKcAUwi3rR+hbxT5VcYF493+Z5kMLI0DL568b7JI4IDJaxWFH0D/xwmGJNoXisyX+w7GH/g==" }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -594,6 +1150,17 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/aria-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz", + "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", @@ -706,6 +1273,20 @@ "deep-equal": "^2.0.5" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -731,6 +1312,11 @@ "node": ">=8" } }, + "node_modules/buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -786,6 +1372,14 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -807,6 +1401,31 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -830,6 +1449,11 @@ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -901,6 +1525,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -923,6 +1552,100 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/embla-carousel": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-7.1.0.tgz", @@ -956,6 +1679,25 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.21.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", @@ -1581,6 +2323,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -1669,6 +2416,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -1874,6 +2629,70 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/html-dom-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-1.2.0.tgz", + "integrity": "sha512-2HIpFMvvffsXHFUFjso0M9LqM+1Lm22BF+Df2ba+7QHJXjk63pWChEnI6YG27eaWqUdfnh5/Vy+OXrNTtepRsg==", + "dependencies": { + "domhandler": "4.3.1", + "htmlparser2": "7.2.0" + } + }, + "node_modules/html-react-parser": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-1.4.12.tgz", + "integrity": "sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ==", + "dependencies": { + "domhandler": "4.3.1", + "html-dom-parser": "1.2.0", + "react-property": "2.0.0", + "style-to-js": "1.1.0" + }, + "peerDependencies": { + "react": "0.14 || 15 || 16 || 17 || 18" + } + }, + "node_modules/html-tokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz", + "integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==", + "dependencies": { + "buffer-from": "~0.1.1", + "inherits": "~2.0.1", + "minimist": "~1.2.5", + "readable-stream": "~1.0.27-1", + "through2": "~0.4.1" + }, + "bin": { + "html-tokenize": "bin/cmd.js" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1919,6 +2738,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -1932,6 +2756,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -1960,6 +2792,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -2261,6 +3098,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2294,6 +3136,14 @@ "node": ">=4.0" } }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -2319,6 +3169,11 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2404,6 +3259,15 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/multipipe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz", + "integrity": "sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==", + "dependencies": { + "duplexer2": "^0.1.2", + "object-assign": "^4.1.0" + } + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -2667,6 +3531,23 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2768,6 +3649,11 @@ "node": ">=14.17" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2833,6 +3719,110 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-property": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz", + "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" + }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -2934,6 +3924,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -3009,6 +4004,14 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -3028,6 +4031,11 @@ "node": ">= 0.4" } }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -3102,6 +4110,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-to-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.0.tgz", + "integrity": "sha512-1OqefPDxGrlMwcbfpsTVRyzwdhr4W0uxYQzeA2F1CBc8WG04udg2+ybRnvh3XYL4TdHQrCahLtax2jc8xaE6rA==", + "dependencies": { + "style-to-object": "0.3.0" + } + }, + "node_modules/style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -3124,6 +4148,11 @@ } } }, + "node_modules/stylis": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3161,6 +4190,11 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tabbable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", + "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -3174,6 +4208,20 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==", + "dependencies": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + } + }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -3183,6 +4231,14 @@ "globrex": "^0.1.2" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3298,6 +4354,89 @@ "punycode": "^2.1.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3373,11 +4512,35 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/xtend/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -3391,6 +4554,93 @@ } }, "dependencies": { + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@babel/runtime": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", @@ -3399,6 +4649,120 @@ "regenerator-runtime": "^0.13.11" } }, + "@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@emotion/babel-plugin": { + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.1", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.1.3" + } + }, + "@emotion/cache": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "requires": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.1", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.1.3" + } + }, + "@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "@emotion/react": { + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", + "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.6", + "@emotion/cache": "^11.10.5", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "requires": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + } + }, + "@emotion/server": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/@emotion/server/-/server-11.10.0.tgz", + "integrity": "sha512-MTvJ21JPo9aS02GdjFW4nhdwOi2tNNpMmAM/YED0pkxzjDNi5WbiTwXqaCnvLc2Lr8NFtjhT0az1vTJyLIHYcw==", + "requires": { + "@emotion/utils": "^1.2.0", + "html-tokenize": "^2.0.0", + "multipipe": "^1.0.2", + "through": "^2.3.8" + } + }, + "@emotion/sheet": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + }, + "@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + }, "@eslint/eslintrc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", @@ -3420,6 +4784,37 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==" }, + "@floating-ui/core": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.4.tgz", + "integrity": "sha512-SQOeVbMwb1di+mVWWJLpsUTToKfqVNioXys011beCAhyOIFtS+GQoW4EQSneuxzmQKddExDwQ+X0hLl4lJJaSQ==" + }, + "@floating-ui/dom": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.4.tgz", + "integrity": "sha512-4+k+BLhtWj+peCU60gp0+rHeR8+Ohqx6kjJf/lHMnJ8JD5Qj6jytcq1+SZzRwD7rvHKRhR7TDiWWddrNrfwQLg==", + "requires": { + "@floating-ui/core": "^1.2.3" + } + }, + "@floating-ui/react": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", + "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", + "requires": { + "@floating-ui/react-dom": "^1.3.0", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" + } + }, + "@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "requires": { + "@floating-ui/dom": "^1.2.1" + } + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3440,6 +4835,90 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "@mantine/carousel": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/carousel/-/carousel-6.0.1.tgz", + "integrity": "sha512-ARwb/Ov4I7zH+3NA42YjSNnv+Tt9dX2BPsmbXaZXhwVTRi2eJZUyLQNsMh8FutlGXbrjtoWrf1DnI96v9CBkpg==", + "requires": { + "@mantine/utils": "6.0.1" + } + }, + "@mantine/core": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.1.tgz", + "integrity": "sha512-RJ0gnEOMQu9qGV9bZxb4FrHe3UT2GjVokzZ91C/Ht8DTu8Ar1uUch45+VsqI67JG2ceHykOMvsDWgAulCUKBNg==", + "requires": { + "@floating-ui/react": "^0.19.1", + "@mantine/styles": "6.0.1", + "@mantine/utils": "6.0.1", + "@radix-ui/react-scroll-area": "1.0.2", + "react-remove-scroll": "^2.5.5", + "react-textarea-autosize": "8.3.4" + } + }, + "@mantine/dates": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.1.tgz", + "integrity": "sha512-ZoKrlEN0YF96Jxr7bFSwZtYm+OSWdc/x8MHFaVmqsN4xkW0WFdv9WyWPLYW+GCeSrw5jcj+XC3dWEY2g/RCacw==", + "requires": { + "@mantine/utils": "6.0.1" + } + }, + "@mantine/form": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.1.tgz", + "integrity": "sha512-oRoe6YnurOzAGUY1DGXTFLofWPEeE8prEdwOv3pJEsp4ggaZAaQQSivIla5yzcsQasptOxMr2Gb8AOk4Ch/WHg==", + "requires": { + "fast-deep-equal": "^3.1.3", + "klona": "^2.0.5" + } + }, + "@mantine/hooks": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.1.tgz", + "integrity": "sha512-D3zWNPMrmjBbns0krXCE5FyWNmrKosYqD+J4/yyBrngvN6XMlmqfUr4C6ofndRrpZHxyshEJgVYLvB5h2bioGQ==", + "requires": {} + }, + "@mantine/next": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/next/-/next-6.0.1.tgz", + "integrity": "sha512-+7Mb79V+ah/XhVmOTQ6tlg0ZHZhweTgryQO9u87wD8KMxuuNhdNLZq27E8390PTXHhxFO93T7k4WbQqIXQOkUg==", + "requires": { + "@mantine/ssr": "6.0.1", + "@mantine/styles": "6.0.1" + } + }, + "@mantine/ssr": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/ssr/-/ssr-6.0.1.tgz", + "integrity": "sha512-qAQEqkVZ6uirdlZzD4ia3yW7PSxITkLjuqHMgabUbfk383xko3MAcdoUHz9cufpB8w+qJzuqUUR9D7mkJCChzQ==", + "requires": { + "@mantine/styles": "6.0.1", + "html-react-parser": "1.4.12" + } + }, + "@mantine/styles": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.1.tgz", + "integrity": "sha512-5hY5Tt0v8GzJ4PSuE9DHlHMmzFi2Vs/l9nVc5feut0vp7GqDvoSMH+gBvsMIIsgGif+nhdztvdpv1aI0YRZgtA==", + "requires": { + "clsx": "1.1.1", + "csstype": "3.0.9" + }, + "dependencies": { + "csstype": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + } + } + }, + "@mantine/utils": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.1.tgz", + "integrity": "sha512-uEN457ELHpKXS4qNAcL5OR9dFOjeFngWRZJVAPkLafWBJuLd2qmdLvKLgUVyt+cMVFtcjnu6rGVOite1+dtaFw==", + "requires": {} + }, "@next/env": { "version": "13.2.3", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.2.3.tgz", @@ -3586,6 +5065,107 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.11.0-57.8fde8fef4033376662cad983758335009d522acb.tgz", "integrity": "sha512-3Vd8Qq06d5xD8Ch5WauWcUUrsVPdMC6Ge8ILji8RFfyhUpqon6qSyGM0apvr1O8n8qH8cKkEFqRPsYjuz5r83g==" }, + "@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-scroll-area": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", + "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, "@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", @@ -3609,6 +5189,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.4.tgz", "integrity": "sha512-VhCw7I7qO2X49+jaKcAUwi3rR+hbxT5VcYF493+Z5kMLI0DL568b7JI4IDJaxWFH0D/xwmGJNoXisyX+w7GH/g==" }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -3725,6 +5310,14 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "aria-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz", + "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==", + "requires": { + "tslib": "^2.0.0" + } + }, "aria-query": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", @@ -3807,6 +5400,16 @@ "deep-equal": "^2.0.5" } }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3829,6 +5432,11 @@ "fill-range": "^7.0.1" } }, + "buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3862,6 +5470,11 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3880,6 +5493,28 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3900,6 +5535,11 @@ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, + "dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3951,6 +5591,11 @@ "object-keys": "^1.1.1" } }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3967,6 +5612,83 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + } + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "embla-carousel": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-7.1.0.tgz", @@ -3994,6 +5716,19 @@ "tapable": "^2.2.0" } }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { "version": "1.21.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", @@ -4471,6 +6206,11 @@ "to-regex-range": "^5.0.1" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4538,6 +6278,11 @@ "has-symbols": "^1.0.3" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -4674,6 +6419,57 @@ "has-symbols": "^1.0.2" } }, + "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==", + "requires": { + "react-is": "^16.7.0" + } + }, + "html-dom-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-1.2.0.tgz", + "integrity": "sha512-2HIpFMvvffsXHFUFjso0M9LqM+1Lm22BF+Df2ba+7QHJXjk63pWChEnI6YG27eaWqUdfnh5/Vy+OXrNTtepRsg==", + "requires": { + "domhandler": "4.3.1", + "htmlparser2": "7.2.0" + } + }, + "html-react-parser": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-1.4.12.tgz", + "integrity": "sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ==", + "requires": { + "domhandler": "4.3.1", + "html-dom-parser": "1.2.0", + "react-property": "2.0.0", + "style-to-js": "1.1.0" + } + }, + "html-tokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz", + "integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==", + "requires": { + "buffer-from": "~0.1.1", + "inherits": "~2.0.1", + "minimist": "~1.2.5", + "readable-stream": "~1.0.27-1", + "through2": "~0.4.1" + } + }, + "htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4707,6 +6503,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -4717,6 +6518,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -4736,6 +6545,11 @@ "is-typed-array": "^1.1.10" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4928,6 +6742,11 @@ "argparse": "^2.0.1" } }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4955,6 +6774,11 @@ "object.assign": "^4.1.3" } }, + "klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==" + }, "language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -4977,6 +6801,11 @@ "type-check": "~0.4.0" } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5038,6 +6867,15 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "multipipe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz", + "integrity": "sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==", + "requires": { + "duplexer2": "^0.1.2", + "object-assign": "^4.1.0" + } + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -5202,6 +7040,17 @@ "callsites": "^3.0.0" } }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5261,6 +7110,11 @@ "@prisma/engines": "4.11.0" } }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5303,6 +7157,70 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-property": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz", + "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" + }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + } + }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + } + }, + "react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + } + } + }, "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -5359,6 +7277,11 @@ "queue-microtask": "^1.2.2" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -5413,6 +7336,11 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -5426,6 +7354,11 @@ "internal-slot": "^1.0.4" } }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -5479,6 +7412,22 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, + "style-to-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.0.tgz", + "integrity": "sha512-1OqefPDxGrlMwcbfpsTVRyzwdhr4W0uxYQzeA2F1CBc8WG04udg2+ybRnvh3XYL4TdHQrCahLtax2jc8xaE6rA==", + "requires": { + "style-to-object": "0.3.0" + } + }, + "style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, "styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -5487,6 +7436,11 @@ "client-only": "0.0.1" } }, + "stylis": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5509,6 +7463,11 @@ "tslib": "^2.5.0" } }, + "tabbable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", + "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -5519,6 +7478,20 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==", + "requires": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + } + }, "tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -5528,6 +7501,11 @@ "globrex": "^0.1.2" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5614,6 +7592,48 @@ "punycode": "^2.1.0" } }, + "use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + } + }, + "use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "requires": {} + }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} + }, + "use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "requires": { + "use-isomorphic-layout-effect": "^1.1.1" + } + }, + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5668,11 +7688,31 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", + "requires": { + "object-keys": "~0.4.0" + }, + "dependencies": { + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" + } + } + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 38034ed..8efa38f 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,23 @@ "build": "next build", "start": "next start", "lint": "next lint", - "format": "npx prettier ./src -w" + "format": "npx prettier ./src -w", + "buildToExport": "bash exporting.sh" }, "dependencies": { + "@emotion/react": "^11.10.6", + "@emotion/server": "^11.10.0", + "@mantine/carousel": "^6.0.1", + "@mantine/core": "^6.0.1", + "@mantine/dates": "^6.0.1", + "@mantine/form": "^6.0.1", + "@mantine/hooks": "^6.0.1", + "@mantine/next": "^6.0.1", "@prisma/client": "^4.11.0", "@types/node": "18.14.4", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", + "dayjs": "^1.11.7", "embla-carousel-react": "^7.1.0", "eslint": "8.35.0", "eslint-config-next": "13.2.3", diff --git a/src/components/Intro.tsx b/src/components/Intro.tsx index de93722..ed4ebb9 100644 --- a/src/components/Intro.tsx +++ b/src/components/Intro.tsx @@ -1,10 +1,9 @@ import customStyles from "@/styles/Custom.module.css"; -import { Inter } from "next/font/google"; -const inter = Inter({ subsets: ["latin"] }); import { SetStateAction, useState } from "react"; -// import { useStateValue, setPhase } from "@/state"; import { Phase } from "@/state/types"; +import { Button,TextInput, List } from '@mantine/core'; + function Intro({ phaseFunction, nameFunction, @@ -21,47 +20,59 @@ function Intro({ function assignName() { nameFunction(name); phaseFunction(Phase.Intro2); - // console.log(Phase.Qsr) - // dispatch(setPhase(Phase.Intro2)); } - // const [, dispatch] = useStateValue(); return (
- */} + + Hoş geldiniz. Bu deneyde sizden bazı olasılıkları + değerlendirmenizi isteyeceğiz. + Oyunlarda kazancınızı "puan" cinsinden + hesaplayacağız. Toplam puanınızın parasal değerini ve ek + olarak bir katılım ücretini size deney sonunda nakit olarak + ödeyeceğiz. + Oyunları tamamladıktan sonra size dair bazı demografik + bilgileri sorduğumuz bir anket olacak. + Deneyden erken ayrılabilirsiniz. Bulunduğunuz sayfayı + değiştirmeniz ve yenilemeniz gibi durumlarda da deneyden + erken ayrılmış sayılacaksınız. Erken ayrılmanız durumunda o + zamana kadarki kararlarınız değerlendirilecek. +
-

+

Çalışmaya katılmayı kabul ediyorum.

- - {name && } + + {name && }
); diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index 047c8dd..5537b11 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -2,17 +2,19 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; import { Inter } from "next/font/google"; -import { useRef, useState, useCallback, useEffect } from "react"; +import { useState, useCallback, useEffect } from "react"; + +import { Button, List } from '@mantine/core'; + -// import { SetStateAction } from "react"; -// import { useStateValue, setPhase } from "@/state"; import { Phase } from "@/state/types"; const inter = Inter({ subsets: ["latin"] }); -import Circles from "./Round"; +import Circles from "./experimentComponents/Circles"; + +import { Carousel,Embla } from '@mantine/carousel'; -import useEmblaCarousel from "embla-carousel-react"; import Slider from "./experimentComponents/Slider"; import BagHolder from "./experimentComponents/BagHolder"; @@ -27,46 +29,43 @@ function Intro2({ treatment: string; phaseFunction: (p: Phase) => void; }) { - // const [instruction, setInstruction] = useState(1); - // const isButtonActive = useRef(true); + const [sliderValue, setSliderValue] = useState(50); const [slideIndex, setSlideIndex] = useState(0); const [showNextPhase, setShowNextPhase] = useState(false); - // const [, dispatch] = useStateValue(); - const [emblaRef, emblaApi] = useEmblaCarousel({ draggable: false }); + const [embla, setEmbla] = useState(null); const scrollPrev = useCallback(() => { - if (emblaApi) emblaApi.scrollPrev(); - setSlideIndex(emblaApi?.selectedScrollSnap() || 0); - }, [emblaApi]); + if (!embla){return;} + embla.scrollPrev(); + setSlideIndex(embla.selectedScrollSnap() || 0); + }, [embla]); const scrollNext = useCallback(() => { - if (emblaApi) emblaApi.scrollNext(); - setSlideIndex(emblaApi?.selectedScrollSnap() || 0); - }, [emblaApi]); + if (!embla){return;} + embla.scrollNext(); + setSlideIndex(embla.selectedScrollSnap() || 0); + }, [embla]); useEffect(() => { - if (slideIndex === 4) { + if (slideIndex === 5) { setShowNextPhase(true); } }, [slideIndex]); return ( <> -
-
-
-
    -
  • + + + + Turlar: Deneyimiz otuz "tur"dan oluşuyor. -
  • -
  • + + Hangi Torbanın Kullanıldığını Tahmin Etme: {" "} @@ -76,8 +75,8 @@ function Intro2({ adetlerde renkli bilye içeren iki tip torba var. Bilgisayarın hangi torbayı seçmiş olabileceğini düşünerek bir karar vermenizi istiyoruz. -
  • -
  • + + Bilgisayar Kullanacağı Torbayı Nasıl Seçiyor: @@ -86,29 +85,29 @@ function Intro2({ 6 sayılarından birini rastgele seçecek. Bunu, tavla zarı gibi altı yüzlü bir zar atışı olarak düşünebilirsiniz. -
      -
    • + + Zar sonucu 1, 2 veya 3 ise, çekiliş daha fazla mavi bilye içeren Mavi torbadan yapılır. -
    • -
    • + + Zar sonucu 4, 5 veya 6 ise, çekiliş daha fazla kırmızı bilye içeren Kırmızı torbadan yapılır. -
    • -
    +
    + Bu nedenle, iki torbanın da seçilme şansı aynıdır. -
  • -
-
-
+ + + + -
-
-
    -
  • + + + + Kullanılan Torba: Zar atışının sonucu size önceden söylenmeyecek, bu nedenle çekiliş için hangi torbanın kullanıldığını bilemezsiniz. @@ -116,8 +115,8 @@ function Intro2({ bu nedenle sizin için kullanılan torba deneye katılan başka bir kişi için kullanılan torbayla aynı olabilir veya olmayabilir. -
  • -
  • + + Çekilişler kişiye özeldir: Bilgisayar zar atışı sonrası kullanılacak torbayı belirlediğinde, o torbadan rastgele çekilecek @@ -127,8 +126,8 @@ function Intro2({ verebilse de, kullanılan torba kişiden kişiye değişebileceğinden, başkaları için kullanılan torba hakkında herhangi bir bilgi sağlamaz. -
  • -
  • + + Çekilişler birbirinden bağımsızdır: Bazı turlarda aynı torbadan birden fazla çekiliş görebilirsiniz. Bunların sonucunu çekiliş @@ -141,13 +140,13 @@ function Intro2({ bir torbanın içindeki bilyelerin sayıları ve renkleri bütün çekilişlerden önce her zaman aynı olacak. -
  • -
-
+ + + -
-
    -
  • + + + Çekilişler birbirinden bağımsızdır: Bazı turlarda aynı torbadan birden fazla çekiliş görebilirsiniz. Bunların sonucunu çekiliş @@ -157,8 +156,8 @@ function Intro2({ gösterecek, torbaya geri koyacak ve rastgele başka bir bilye çekmeden önce torbayı tekrar karıştıracakmışız gibi düşünebilirsiniz. -
  • -
  • + + Her çekiliş sonrası bilye torbaya geri konur: @@ -167,16 +166,16 @@ function Intro2({ konmuş gibi olur. Yani bir torbanın içindeki bilyelerin sayıları ve renkleri bütün çekilişlerden önce her zaman aynı olacak. -
  • -
  • + + Çekiliş sonuçlarını gördükten sonra, kullanılan torbanın Kırmızı torba olma ihtimalinin{" "} 100’de kaç olduğuna {" "} karar vermelisiniz. -
  • -
  • + + O tur, hiç çekiliş yapılmayan bir tursa, kararınızı tamamen zar atışının kullanılan torbayı nasıl belirlendiğine dayandırmanız @@ -185,13 +184,13 @@ function Intro2({ seçildiğine hem de alakalı çekiliş veya çekilişlerin sonucuna ilişkin bilgileri kullanabilirsiniz. -
  • -
-
+ + + -
-
    -
  • + + + Şayet kararınız 0 ise, bu Kırmızı torbanın kullanılma ihtimalinin olmadığını düşündüğünüz anlamına gelir. Kararınız 100 ise, Kırmızı @@ -204,7 +203,7 @@ function Intro2({ bir sayı seçin. Mavi torbanın kullanılma ihtimalinin daha yüksek olduğunu düşünüyorsanız 50'nin altında bir sayı seçin. -
  • +
    Sizce, seçilen torbanın{" "} @@ -224,7 +222,6 @@ function Intro2({
    Sizce, seçilen torbanın{" "} @@ -232,36 +229,91 @@ function Intro2({ {" "} olma ihtimali: Yüzde {100 - sliderValue}.
    -
-
-
-
+ + + + {treatment==="QSR" ? + (
+ + + + Burada kaydırıcıyı sağa ya da sola sürükleyerek size göre Kırmızı torbanın kullanılmış olma ihtimalini bildireceksiniz. Bu esnada aşağıdaki kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini görebilirsiniz. Daha büyük bir simit daha çok kazanca karşılık gelir ve bu miktarın nasıl değiştiği de kaydırıcı hareket ettikçe görülebilir. + + + Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Şayet o turda Kırmızı torba kullanılmış ise, kazancınız kırmızı simidin karşılık geldiği miktar olacak. Şayet o turda Mavi torba kullanılmış ise, kazancınız mavi simidin karşılık geldiği miktar olacak. + + +
+ { + setSliderValue(Number(event.target.value)); + }} + /> + + +
+
+ ): + (
+ + + + Burada kaydırıcıyı sağa ya da sola sürükleyerek size göre Kırmızı torbanın kullanılmış olma ihtimalini bildireceksiniz. Bu esnada aşağıdaki kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini görebilirsiniz. + + + Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Ardından, seçilen torbanın rengindeki simit ve içindeki alanın teşkil ettiği daireden rastgele bir nokta seçilecek. + + + Eğer bu nokta ilgili simite, yani tam dairenin renkli kısmına denk düşerse, kazancınız 1000 puan, aksi takdirde 0 puan olacak. + + +
+ { + setSliderValue(Number(event.target.value)); + }} + /> + + +
+
+ ) + } +
+ {slideIndex + 1} -
- - + {showNextPhase && ( - + )} -
+ {/* */} + ); } diff --git a/src/components/Round.tsx b/src/components/Round.tsx index d2e85de..b60a66c 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -6,6 +6,8 @@ import Drawing from "./experimentComponents/Drawing"; import BagHolder from "./experimentComponents/BagHolder"; import customStyles from "@/styles/Custom.module.css"; +import { Button } from "@mantine/core"; + import { Inter } from "next/font/google"; import { Round } from "@prisma/client"; import { DrawingT, Phase } from "@/state/types"; @@ -143,14 +145,14 @@ function Round({ {subPhase === "result" && (
{`${calculatePointsForRound()} kazandınız.`}
)} - + )} diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index c9a5509..aa0671f 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -1,50 +1,47 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; - -import { Inter } from "next/font/google"; - -const inter = Inter({ subsets: ["latin"] }); +import { Text } from '@mantine/core'; function BagHolder({ aBlue, bBlue }: { aBlue: number; bBlue: number }) { return (
-
-
+
+ Mavi Torba:{" "} {bBlue} adet{" "} mavi bilye,{" "} {100 - bBlue} adet{" "} kırmızı bilye -
-
+ +
{[...Array(bBlue)].map((e, i) => ( - 🔵 +
🔵
))} {[...Array(100 - bBlue)].map((e, i) => ( - 🔴 +
🔴
))}
-
Zar sonucu 4,5 veya 6 ise kullanılır.
+ Zar sonucu 1,2 veya 3 ise kullanılır.
-
-
+
+ Kırmızı Torba:{" "} {aBlue} adet{" "} mavi bilye,{" "} {100 - aBlue} adet{" "} kırmızı bilye -
+ -
+
{[...Array(aBlue)].map((e, i) => ( - 🔵 +
🔵
))} {[...Array(100 - aBlue)].map((e, i) => ( - 🔴 +
🔴
))}
-
Zar sonucu 1, 2 veya 3 ise kullanılır.
+ Zar sonucu 4,5 veya 6 ise kullanılır.
); diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index b3cde76..cfa0208 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -1,10 +1,10 @@ import { useRef } from "react"; -import { Inter } from "next/font/google"; -const inter = Inter({ subsets: ["latin"] }); import customStyles from "@/styles/Custom.module.css"; import { DrawingT } from "@/state/types"; +import { Button } from "@mantine/core"; + // import { useStateValue, updateRound } from "@/state"; interface drawingProps { @@ -53,7 +53,7 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { return ( <> -

+

Çekilen toplar:

))}
- + ); } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 6b97e8a..54db4c5 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,6 +1,43 @@ -import "@/styles/globals.css"; -import type { AppProps } from "next/app"; +// import "@/styles/globals.css"; +// import type { AppProps } from "next/app"; -export default function App({ Component, pageProps }: AppProps) { - return ; -} +// export default function App({ Component, pageProps }: AppProps) { +// return ; +// } + +import { AppProps } from 'next/app'; +import Head from 'next/head'; +import { MantineProvider } from '@mantine/core'; + +export default function App(props: AppProps) { + const { Component, pageProps } = props; + + return ( + <> + + + Ekonomi Deneyi + + + + + + + + + + ); +} \ No newline at end of file diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index b4a3784..c757e51 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,13 +1,21 @@ -import { Html, Head, Main, NextScript } from "next/document"; +import Document,{ Html, Head, Main, NextScript } from "next/document"; +import { createGetInitialProps } from '@mantine/next'; -export default function Document() { - return ( - - - -
- - +const getInitialProps = createGetInitialProps(); + + +export default class _Document extends Document { + static getInitialProps = getInitialProps; + + render() { + return ( + + + +
+ + - ); -} + ); + } + } \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 2e0e8e4..3521fa4 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -14,18 +14,7 @@ export default function Home({ // console.log(data) return ( <> - - Ekonomi Deneyi - - - - + <> {/* */} @@ -36,15 +25,35 @@ export default function Home({ ); } +const defaultSession:Omit = { + // id: 'placeholderSession', + start_time: new Date(), + end_time: null, + name: 'alpha_1', + location: null, + num_of_blue_a: 30, + num_of_blue_b: 70, + treatment: 'QSR', + drawn_balls: [ + 1, 1, 2, 2, 3, + 3, 4, 4, 5, 5, + 6, 6 + ], + prior: [ 3, 3 ] +} + export const getServerSideProps: GetServerSideProps<{ data: Session; }> = async () => { - const sessionData = (await prisma.session.findFirst()) as Session; + let sessionData = (await prisma.session.findFirst()); + + if (sessionData===null){ + sessionData = await prisma.session.create({data: {...defaultSession}}); + } sessionData.start_time = JSON.parse( JSON.stringify(sessionData?.start_time) ); sessionData.end_time = JSON.parse(JSON.stringify(sessionData?.end_time)); - // console.log(sessionData) return { props: { diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 2278680..1b10774 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -10,6 +10,10 @@ margin-top: 0.75em; } +/* .mantine-List-item{ + list-style-position: inside !important; +} */ + .mainWrapper { max-width: 1200px; } @@ -49,14 +53,17 @@ display: flex; gap: 10%; /* margin: 5% 10%; */ - margin-bottom: 10ch; + /* margin-bottom: 10ch; */ + margin-inline: auto; width: 1000px; justify-content: center; } .bagHolder > * { padding: 2ch; - width: 26ch; + /* margin-inline:auto; */ + /* text-align: center; */ + /* width: 26ch; */ } /* div.__className_4b5723:nth-child(1) > div */ .bagHolder > :nth-child(1) > :not(:last-child), @@ -74,7 +81,15 @@ border-radius: 3ch; } -.embla { +.ballHolder{ + display: grid; + grid-template-columns: repeat(10, 1fr); + font-size: 3vh; + grid-gap: 0px; + line-height: 2ch; +} + +/* .embla { overflow: hidden; margin: 0px; } @@ -88,7 +103,7 @@ .embla__slide > ul > li { list-style-position: inside; -} +} */ .navButton { font-size: 24px; @@ -117,7 +132,7 @@ padding-bottom:20px; padding-right: calc(50vw - 600px); box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; - /* background-color: turquoise; */ + background-color: rgb(226, 241, 247); margin-top: auto; } From 168ea5496f03931a3402caa3fc892c4ed8a7b7a2 Mon Sep 17 00:00:00 2001 From: emrergin Date: Thu, 16 Mar 2023 17:14:04 +0300 Subject: [PATCH 02/24] rounds are connected to the database --- README.md | 5 +- .../migration.sql | 8 + prisma/schema.prisma | 1 + src/components/Experiment.tsx | 26 +- src/components/Footer.tsx | 18 +- src/components/Intro.tsx | 51 +- src/components/Intro2.tsx | 511 ++++++++++-------- src/components/Round.tsx | 67 ++- .../experimentComponents/BagHolder.tsx | 10 +- .../experimentComponents/Circles.tsx | 17 +- .../experimentComponents/Drawing.tsx | 7 +- src/pages/_app.tsx | 63 ++- src/pages/_document.tsx | 27 +- src/pages/admin/index.tsx | 57 +- src/pages/api/participant.ts | 18 + src/pages/api/round.ts | 18 + src/pages/index.tsx | 38 +- src/state/index.ts | 2 - src/state/reducer.ts | 47 -- src/state/state.tsx | 36 -- src/styles/Circles.module.css | 5 + src/styles/Custom.module.css | 40 +- 22 files changed, 557 insertions(+), 515 deletions(-) create mode 100644 prisma/migrations/20230316134936_added_number_of_round/migration.sql create mode 100644 src/pages/api/participant.ts create mode 100644 src/pages/api/round.ts delete mode 100644 src/state/index.ts delete mode 100644 src/state/reducer.ts delete mode 100644 src/state/state.tsx diff --git a/README.md b/README.md index 1e3101d..61089d2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Joint project with [Mehmet Yiğit Gürdal](https://econ.boun.edu.tr/mehmet-yigit ## Technologies Used - **Next.js** as the **React** framework. -- Next.js **API routes** for server-side API routes as the backend. +- Next.js **API routes** as the backend. - **Prisma** as the ORM for migrations and database access. - **PostgreSQL** as the database. - **TypeScript** as the programming language. @@ -22,4 +22,5 @@ Some introductory readings for the concepts. - https://academic.oup.com/restud/article-abstract/80/3/984/1573566 ## Sources -- https://stackoverflow.com/questions/34189370/how-to-repeat-an-element-n-times-using-jsx-and-lodash \ No newline at end of file +- https://stackoverflow.com/questions/34189370/how-to-repeat-an-element-n-times-using-jsx-and-lodash +- https://blog.logrocket.com/effortless-database-schema-migration-prisma/ \ No newline at end of file diff --git a/prisma/migrations/20230316134936_added_number_of_round/migration.sql b/prisma/migrations/20230316134936_added_number_of_round/migration.sql new file mode 100644 index 0000000..e73176d --- /dev/null +++ b/prisma/migrations/20230316134936_added_number_of_round/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `round` to the `Round` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Round" ADD COLUMN "round" INTEGER NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index eedb41b..e79f8a8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -46,6 +46,7 @@ model Round { fourth_draw_blue Boolean? fifth_draw_blue Boolean? sixth_draw_blue Boolean? + round Int reward Int participantId String Participant Participant @relation(fields: [participantId], references: [id]) diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index 926969a..c5bd389 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -6,10 +6,13 @@ import Intro2 from "@/components/Intro2"; import Footer from "./Footer"; -import { Session } from "@prisma/client"; -import { useEffect, useRef, useState } from "react"; +import { Participant, Session } from "@prisma/client"; +import { useRef, useState } from "react"; + import Round from "@/components/Round"; +import { Phase } from "@/state/types"; + function shuffle(array: number[]) { let resArray = array; for (let i = resArray.length - 1; i > 0; i--) { @@ -20,12 +23,18 @@ function shuffle(array: number[]) { } function Experiment({ data }: { data: Session }) { + const [participant, setParticipant] = useState>({}); + + async function generateNewParticipant(name: string) { + const respond = await fetch("/belief/api/participant", { + method: "POST", + body: JSON.stringify({ name_surname: name, sessionId: data.id }), + }); + setParticipant(await respond.json()); + setPhase(Phase.Intro2); + } - useEffect(()=>{ - console.log(data); - },[data]); const [phase, setPhase] = useState("INTRO"); - const [name, setName] = useState(""); const randomizedDraws = useRef(shuffle(data.drawn_balls)); const [points, setPoints] = useState(0); @@ -35,7 +44,7 @@ function Experiment({ data }: { data: Session }) { {phase} - {data.treatment}

{phase === "INTRO" && ( - + )} {phase === "INTRO2" && ( )} {phase === "END" && (
Deney Bitti. Kazandığınız toplam puan: {points}
)} -
+
); } diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 0a7c643..a76968c 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,12 +1,14 @@ import customStyles from "@/styles/Custom.module.css"; - -function Footer(){ - return( - - ) +function Footer() { + return ( + + ); } -export default Footer; \ No newline at end of file +export default Footer; diff --git a/src/components/Intro.tsx b/src/components/Intro.tsx index ed4ebb9..b654f08 100644 --- a/src/components/Intro.tsx +++ b/src/components/Intro.tsx @@ -1,14 +1,13 @@ import customStyles from "@/styles/Custom.module.css"; import { SetStateAction, useState } from "react"; -import { Phase } from "@/state/types"; -import { Button,TextInput, List } from '@mantine/core'; +import { Button, TextInput, List } from "@mantine/core"; function Intro({ - phaseFunction, + // phaseFunction, nameFunction, }: { - phaseFunction: (a: Phase) => void; + // phaseFunction: (a: Phase) => void; nameFunction: (a: string) => void; }) { const [name, setName] = useState(""); @@ -17,9 +16,9 @@ function Intro({ setName(event.target.value); }; - function assignName() { + async function assignName() { nameFunction(name); - phaseFunction(Phase.Intro2); + // phaseFunction(Phase.Intro2); } return ( @@ -47,32 +46,42 @@ function Intro({ */} - Hoş geldiniz. Bu deneyde sizden bazı olasılıkları - değerlendirmenizi isteyeceğiz. - Oyunlarda kazancınızı "puan" cinsinden + + Hoş geldiniz. Bu deneyde sizden bazı olasılıkları + değerlendirmenizi isteyeceğiz. + + + Oyunlarda kazancınızı "puan" cinsinden hesaplayacağız. Toplam puanınızın parasal değerini ve ek olarak bir katılım ücretini size deney sonunda nakit olarak - ödeyeceğiz. - Oyunları tamamladıktan sonra size dair bazı demografik - bilgileri sorduğumuz bir anket olacak. - Deneyden erken ayrılabilirsiniz. Bulunduğunuz sayfayı + ödeyeceğiz. + + + Oyunları tamamladıktan sonra size dair bazı demografik + bilgileri sorduğumuz bir anket olacak. + + + Deneyden erken ayrılabilirsiniz. Bulunduğunuz sayfayı değiştirmeniz ve yenilemeniz gibi durumlarda da deneyden erken ayrılmış sayılacaksınız. Erken ayrılmanız durumunda o - zamana kadarki kararlarınız değerlendirilecek. + zamana kadarki kararlarınız değerlendirilecek. +
-

- Çalışmaya katılmayı kabul ediyorum. -

- Çalışmaya katılmayı kabul ediyorum.

+ - - {name && } + + {name && ( + + )}
); diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index 5537b11..c7af333 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -1,19 +1,15 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; -import { Inter } from "next/font/google"; -import { useState, useCallback, useEffect } from "react"; - -import { Button, List } from '@mantine/core'; +import { useState, useCallback, useEffect } from "react"; +import { Button, List } from "@mantine/core"; import { Phase } from "@/state/types"; -const inter = Inter({ subsets: ["latin"] }); - import Circles from "./experimentComponents/Circles"; -import { Carousel,Embla } from '@mantine/carousel'; +import { Carousel, Embla } from "@mantine/carousel"; import Slider from "./experimentComponents/Slider"; import BagHolder from "./experimentComponents/BagHolder"; @@ -29,22 +25,24 @@ function Intro2({ treatment: string; phaseFunction: (p: Phase) => void; }) { - const [sliderValue, setSliderValue] = useState(50); const [slideIndex, setSlideIndex] = useState(0); const [showNextPhase, setShowNextPhase] = useState(false); - const [embla, setEmbla] = useState(null); const scrollPrev = useCallback(() => { - if (!embla){return;} + if (!embla) { + return; + } embla.scrollPrev(); setSlideIndex(embla.selectedScrollSnap() || 0); }, [embla]); const scrollNext = useCallback(() => { - if (!embla){return;} + if (!embla) { + return; + } embla.scrollNext(); setSlideIndex(embla.selectedScrollSnap() || 0); }, [embla]); @@ -54,265 +52,306 @@ function Intro2({ setShowNextPhase(true); } }, [slideIndex]); - + return ( <> - - - - - Turlar: Deneyimiz otuz "tur"dan - oluşuyor. - - - - Hangi Torbanın Kullanıldığını Tahmin Etme: - {" "} - Her turda, bilgisayarı bir "torba"dan, - bir veya daha fazla renkli bilye çekilişini - simüle etmek için kullanacağız. İçlerinde farklı - adetlerde renkli bilye içeren iki tip torba var. - Bilgisayarın hangi torbayı seçmiş olabileceğini - düşünerek bir karar vermenizi istiyoruz. - - - - Bilgisayar Kullanacağı Torbayı Nasıl - Seçiyor: - {" "} - Her turda bilgisayar ilk olarak, 1, 2, 3, 4, 5, - 6 sayılarından birini rastgele seçecek. Bunu, - tavla zarı gibi altı yüzlü bir zar atışı olarak - düşünebilirsiniz. - - - Zar sonucu 1, 2 veya 3 ise, çekiliş daha - fazla mavi bilye içeren Mavi torbadan - yapılır. - - - Zar sonucu 4, 5 veya 6 ise, çekiliş daha - fazla kırmızı bilye içeren Kırmızı - torbadan yapılır. - - - Bu nedenle, iki torbanın da seçilme şansı - aynıdır. - - - - - - - - - - Kullanılan Torba: Zar atışının sonucu - size önceden söylenmeyecek, bu nedenle çekiliş - için hangi torbanın kullanıldığını bilemezsiniz. - Zar, her turda her kişi için ayrı ayrı atılır, - bu nedenle sizin için kullanılan torba deneye - katılan başka bir kişi için kullanılan torbayla - aynı olabilir veya olmayabilir. - - - Çekilişler kişiye özeldir: Bilgisayar zar - atışı sonrası kullanılacak torbayı - belirlediğinde, o torbadan rastgele çekilecek - bir veya daha fazla bilye gösterilebilir. Bu - çekilişler size sizin gördüğünüz değerler için - hangi torbanın kullanıldığı hakkında bilgi - verebilse de, kullanılan torba kişiden kişiye - değişebileceğinden, başkaları için kullanılan - torba hakkında herhangi bir bilgi sağlamaz. - - - Çekilişler birbirinden bağımsızdır: Bazı - turlarda aynı torbadan birden fazla çekiliş - görebilirsiniz. Bunların sonucunu çekiliş - sırasıyla göreceksiniz. Çekilişler bağımsız - olarak yapılacak, yani sanki torbayı sallayacak, - içinden rastgele bir bilye seçecek, bilyeyi size - gösterecek, torbaya geri koyacak ve rastgele - başka bir bilye çekmeden önce torbayı tekrar - karıştıracakmışız gibi düşünebilirsiniz. Yani - bir torbanın içindeki bilyelerin sayıları ve - renkleri bütün çekilişlerden önce her zaman aynı - olacak. - - - + + + + + Turlar: Deneyimiz otuz "tur"dan + oluşuyor. + + + Hangi Torbanın Kullanıldığını Tahmin Etme:{" "} + Her turda, bilgisayarı bir "torba"dan, bir + veya daha fazla renkli bilye çekilişini simüle etmek + için kullanacağız. İçlerinde farklı adetlerde renkli + bilye içeren iki tip torba var. Bilgisayarın hangi + torbayı seçmiş olabileceğini düşünerek bir karar + vermenizi istiyoruz. + + + Bilgisayar Kullanacağı Torbayı Nasıl Seçiyor:{" "} + Her turda bilgisayar ilk olarak, 1, 2, 3, 4, 5, 6 + sayılarından birini rastgele seçecek. Bunu, tavla + zarı gibi altı yüzlü bir zar atışı olarak + düşünebilirsiniz. + + + Zar sonucu 1, 2 veya 3 ise, çekiliş daha + fazla mavi bilye içeren{" "} + + Mavi torba + + dan yapılır. + + + Zar sonucu 4, 5 veya 6 ise, çekiliş daha + fazla kırmızı bilye içeren{" "} + + Kırmızı torba + + dan yapılır. + + + Bu nedenle, iki torbanın da seçilme şansı aynıdır. + + + + + + + + + + Kullanılan Torba: Zar atışının sonucu size + önceden söylenmeyecek, bu nedenle çekiliş için hangi + torbanın kullanıldığını bilemezsiniz. Zar, her turda + her kişi için ayrı ayrı atılır, bu nedenle sizin + için kullanılan torba deneye katılan başka bir kişi + için kullanılan torbayla aynı olabilir veya + olmayabilir. + + + Çekilişler kişiye özeldir: Bilgisayar zar + atışı sonrası kullanılacak torbayı belirlediğinde, o + torbadan rastgele çekilecek bir veya daha fazla + bilye gösterilebilir. Bu çekilişler size sizin + gördüğünüz değerler için hangi torbanın kullanıldığı + hakkında bilgi verebilse de, kullanılan torba + kişiden kişiye değişebileceğinden, başkaları için + kullanılan torba hakkında herhangi bir bilgi + sağlamaz. + + + Çekilişler birbirinden bağımsızdır: Bazı + turlarda aynı torbadan birden fazla çekiliş + görebilirsiniz. Bunların sonucunu çekiliş sırasıyla + göreceksiniz. Çekilişler bağımsız olarak yapılacak, + yani sanki torbayı sallayacak, içinden rastgele bir + bilye seçecek, bilyeyi size gösterecek, torbaya geri + koyacak ve rastgele başka bir bilye çekmeden önce + torbayı tekrar karıştıracakmışız gibi + düşünebilirsiniz. Yani bir torbanın içindeki + bilyelerin sayıları ve renkleri bütün çekilişlerden + önce her zaman aynı olacak. + + + - - - - Çekilişler birbirinden bağımsızdır: Bazı - turlarda aynı torbadan birden fazla çekiliş - görebilirsiniz. Bunların sonucunu çekiliş - sırasıyla göreceksiniz. Çekilişler bağımsız - olarak yapılacak, yani sanki torbayı sallayacak, - içinden rastgele bir bilye seçecek, bilyeyi size - gösterecek, torbaya geri koyacak ve rastgele - başka bir bilye çekmeden önce torbayı tekrar - karıştıracakmışız gibi düşünebilirsiniz. - - - - Her çekiliş sonrası bilye torbaya geri - konur: - {" "} - Çekilen bilye, her çekilişten sonra torbaya geri - konmuş gibi olur. Yani bir torbanın içindeki - bilyelerin sayıları ve renkleri bütün - çekilişlerden önce her zaman aynı olacak. - - - Çekiliş sonuçlarını gördükten sonra, kullanılan - torbanın Kırmızı torba olma ihtimalinin{" "} - - 100’de kaç olduğuna - {" "} - karar vermelisiniz. - - - O tur, hiç çekiliş yapılmayan bir tursa, - kararınızı tamamen zar atışının kullanılan - torbayı nasıl belirlendiğine dayandırmanız - gerekir. Aksi takdirde, torbaların içeriğini göz - önünde bulundurarak hem torbanın nasıl - seçildiğine hem de alakalı çekiliş veya - çekilişlerin sonucuna ilişkin bilgileri - kullanabilirsiniz. - - - + + + + Çekilişler birbirinden bağımsızdır: Bazı + turlarda aynı torbadan birden fazla çekiliş + görebilirsiniz. Bunların sonucunu çekiliş sırasıyla + göreceksiniz. Çekilişler bağımsız olarak yapılacak, + yani sanki torbayı sallayacak, içinden rastgele bir + bilye seçecek, bilyeyi size gösterecek, torbaya geri + koyacak ve rastgele başka bir bilye çekmeden önce + torbayı tekrar karıştıracakmışız gibi + düşünebilirsiniz. + + + Her çekiliş sonrası bilye torbaya geri konur:{" "} + Çekilen bilye, her çekilişten sonra torbaya geri + konmuş gibi olur. Yani bir torbanın içindeki + bilyelerin sayıları ve renkleri bütün çekilişlerden + önce her zaman aynı olacak. + + + Çekiliş sonuçlarını gördükten sonra, kullanılan + torbanın Kırmızı torba olma ihtimalinin{" "} + + 100’de kaç olduğuna + {" "} + karar vermelisiniz. + + + O tur, hiç çekiliş yapılmayan bir tursa, kararınızı + tamamen zar atışının kullanılan torbayı nasıl + belirlendiğine dayandırmanız gerekir. Aksi takdirde, + torbaların içeriğini göz önünde bulundurarak hem + torbanın nasıl seçildiğine hem de alakalı çekiliş + veya çekilişlerin sonucuna ilişkin bilgileri + kullanabilirsiniz. + + + - - - - Şayet kararınız 0 ise, bu Kırmızı torbanın - kullanılma ihtimalinin olmadığını düşündüğünüz - anlamına gelir. Kararınız 100 ise, Kırmızı - torbanın kullanıldığından kesinlikle emin - olduğunuz anlamına gelir. Kararınız 50 ise, her - bir torbanın kullanılmış olma ihtimalinin eşit - olduğunu düşündüğünüz anlamına gelir. Kırmızı - torbanın kullanılma ihtimalinin daha yüksek - olduğunu düşünüyorsanız, 50'nin üzerinde - bir sayı seçin. Mavi torbanın kullanılma - ihtimalinin daha yüksek olduğunu düşünüyorsanız - 50'nin altında bir sayı seçin. - + + + + Şayet kararınız 0 ise, bu Kırmızı torbanın + kullanılma ihtimalinin olmadığını düşündüğünüz + anlamına gelir. Kararınız 100 ise, Kırmızı torbanın + kullanıldığından kesinlikle emin olduğunuz anlamına + gelir. Kararınız 50 ise, her bir torbanın + kullanılmış olma ihtimalinin eşit olduğunu + düşündüğünüz anlamına gelir. Kırmızı torbanın + kullanılma ihtimalinin daha yüksek olduğunu + düşünüyorsanız, 50'nin üzerinde bir sayı seçin. + Mavi torbanın kullanılma ihtimalinin daha yüksek + olduğunu düşünüyorsanız 50'nin altında bir sayı + seçin. + - { - setSliderValue(Number(event.target.value)); - }} - /> -
- Sizce, seçilen torbanın{" "} - - kırmızı torba - {" "} - olma ihtimali: Yüzde {sliderValue}. -
+ { + setSliderValue(Number(event.target.value)); + }} + /> +
+ Sizce, seçilen torbanın{" "} + + kırmızı torba + {" "} + olma ihtimali: Yüzde {sliderValue}. +
+
+ Sizce, seçilen torbanın{" "} + mavi torba{" "} + olma ihtimali: Yüzde {100 - sliderValue}. +
+
+
+ + {treatment === "QSR" ? ( +
+ + + Burada kaydırıcıyı sağa ya da sola + sürükleyerek size göre Kırmızı torbanın + kullanılmış olma ihtimalini bildireceksiniz. + Bu esnada aşağıdaki kırmızı simidin ve mavi + simidin büyüklüklerinin değiştiğini + görebilirsiniz. Daha büyük bir simit daha + çok kazanca karşılık gelir ve bu miktarın + nasıl değiştiği de kaydırıcı hareket ettikçe + görülebilir. + + + Karar verdikten sonra, gerçekte hangi + torbanın kullanıldığı size bildirilecektir. + Şayet o turda Kırmızı torba kullanılmış ise, + kazancınız kırmızı simidin karşılık geldiği + miktar olacak. Şayet o turda Mavi torba + kullanılmış ise, kazancınız mavi simidin + karşılık geldiği miktar olacak. + +
- Sizce, seçilen torbanın{" "} - - mavi torba - {" "} - olma ihtimali: Yüzde {100 - sliderValue}. + { + setSliderValue( + Number(event.target.value) + ); + }} + /> +
- - - - {treatment==="QSR" ? - (
- +
+ ) : ( +
- Burada kaydırıcıyı sağa ya da sola sürükleyerek size göre Kırmızı torbanın kullanılmış olma ihtimalini bildireceksiniz. Bu esnada aşağıdaki kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini görebilirsiniz. Daha büyük bir simit daha çok kazanca karşılık gelir ve bu miktarın nasıl değiştiği de kaydırıcı hareket ettikçe görülebilir. + Burada kaydırıcıyı sağa ya da sola + sürükleyerek size göre Kırmızı torbanın + kullanılmış olma ihtimalini bildireceksiniz. + Bu esnada aşağıdaki kırmızı simidin ve mavi + simidin büyüklüklerinin değiştiğini + görebilirsiniz. + + + Karar verdikten sonra, gerçekte hangi + torbanın kullanıldığı size bildirilecektir. + Ardından, seçilen torbanın rengindeki simit + ve içindeki alanın teşkil ettiği daireden + rastgele bir nokta seçilecek. - Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Şayet o turda Kırmızı torba kullanılmış ise, kazancınız kırmızı simidin karşılık geldiği miktar olacak. Şayet o turda Mavi torba kullanılmış ise, kazancınız mavi simidin karşılık geldiği miktar olacak. + Eğer bu nokta ilgili simite, yani tam + dairenin renkli kısmına denk düşerse, + kazancınız 1000 puan, aksi takdirde 0 puan + olacak. -
- { - setSliderValue(Number(event.target.value)); +
- - -
-
- ): - (
- - - - Burada kaydırıcıyı sağa ya da sola sürükleyerek size göre Kırmızı torbanın kullanılmış olma ihtimalini bildireceksiniz. Bu esnada aşağıdaki kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini görebilirsiniz. - - - Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Ardından, seçilen torbanın rengindeki simit ve içindeki alanın teşkil ettiği daireden rastgele bir nokta seçilecek. - - - Eğer bu nokta ilgili simite, yani tam dairenin renkli kısmına denk düşerse, kazancınız 1000 puan, aksi takdirde 0 puan olacak. - - -
- + { - setSliderValue(Number(event.target.value)); + setSliderValue( + Number(event.target.value) + ); }} - /> - - -
-
- ) - } - + /> + +
+
+ )} +
{slideIndex + 1} - {/*
*/} - - {showNextPhase && ( - )} - {/*
*/} ); diff --git a/src/components/Round.tsx b/src/components/Round.tsx index b60a66c..a55d0a5 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -13,9 +13,9 @@ import { Round } from "@prisma/client"; import { DrawingT, Phase } from "@/state/types"; const inter = Inter({ subsets: ["latin"] }); -interface SubTypeRound extends DrawingT{ - is_blue: boolean, - decision_time: number +interface SubTypeRound extends DrawingT { + is_blue: boolean; + decision_time: number; } function Round({ @@ -26,6 +26,7 @@ function Round({ bBlue, phaseFunction, pointFunction, + participantId, }: { bsr: boolean; arrayOfDraws: number[]; @@ -34,13 +35,16 @@ function Round({ bBlue: number; phaseFunction: (p: Phase) => void; pointFunction: (p: number) => void; + participantId: string; }) { const [redRatio, setRedRatio] = useState(50); const [currentRound, setCurrentRound] = useState(1); - const [selectedBag, setSelectedBag] = useState<0 | 1>( - Math.random() < priors[0] / (priors[0] + priors[1]) ? 0 : 1 + const [selectedBag, setSelectedBag] = useState<"blue" | "red">( + Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" : "red" ); - const roundData = useRef>({}); + const roundData = useRef>({ + is_blue: selectedBag === "blue", + }); const [subPhase, setSubPhase] = useState<"drawing" | "input" | "result">( "drawing" ); @@ -57,9 +61,8 @@ function Round({ if (subPhase === "input") { roundData.current = { ...roundData.current, - decision_time: Number(new Date())-Number(time.current) - - } + decision_time: Number(new Date()) - Number(time.current), + }; setSubPhase("result"); } else { nextRound(); @@ -76,45 +79,55 @@ function Round({ } function calculatePointsForRound() { - if (selectedBag === 0) { + if (selectedBag === "blue") { return (100 - redRatio) ** 2; } else { return redRatio ** 2; } } + async function generateNewRound(lastRound: Omit) { + const respond = await fetch("/belief/api/round", { + method: "POST", + body: JSON.stringify(lastRound), + }); + } + function nextRound() { - const lastRound:Round ={ + const lastRound: Omit = { ...(roundData.current as SubTypeRound), // decision_time: 0, - participantId: "0", - id: crypto.randomUUID(), - chosen_probability: 100-redRatio, + participantId: participantId, + // id: crypto.randomUUID(), + chosen_probability: 100 - redRatio, // is_blue: selectedBag===0, - reward:calculatePointsForRound() - } + reward: calculatePointsForRound(), + round: currentRound, + }; console.log(lastRound); + generateNewRound(lastRound); setPoint(calculatePointsForRound() + point); pointFunction(calculatePointsForRound() + point); if (currentRound < numberOfRounds) { const newBag = - Math.random() < priors[0] / (priors[0] + priors[1]) ? 0 : 1; + Math.random() < priors[0] / (priors[0] + priors[1]) + ? "blue" + : "red"; setSelectedBag(newBag); setSubPhase("drawing"); - roundData.current={ + roundData.current = { ...roundData.current, - is_blue: newBag === 1 ? true : false, + is_blue: newBag === "blue" ? true : false, }; setCurrentRound(currentRound + 1); setRedRatio(50); time.current = new Date(); - } else{ + } else { phaseFunction(Phase.End); pointFunction(point); } } - return (
@@ -123,7 +136,7 @@ function Round({ endDrawing(d)} /> @@ -143,16 +156,13 @@ function Round({ /> {subPhase === "result" && ( -
+
{`${calculatePointsForRound()} kazandınız.`}
)} -
); } diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index aa0671f..57fccf0 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -1,12 +1,12 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; -import { Text } from '@mantine/core'; +import { Text } from "@mantine/core"; function BagHolder({ aBlue, bBlue }: { aBlue: number; bBlue: number }) { return (
- + Mavi Torba:{" "} {bBlue} adet{" "} mavi bilye,{" "} @@ -21,10 +21,10 @@ function BagHolder({ aBlue, bBlue }: { aBlue: number; bBlue: number }) {
🔴
))}
- Zar sonucu 1,2 veya 3 ise kullanılır. + Zar sonucu 1,2 veya 3 ise kullanılır.
- + Kırmızı Torba:{" "} {aBlue} adet{" "} mavi bilye,{" "} @@ -41,7 +41,7 @@ function BagHolder({ aBlue, bBlue }: { aBlue: number; bBlue: number }) { ))}
- Zar sonucu 4,5 veya 6 ise kullanılır. + Zar sonucu 4,5 veya 6 ise kullanılır.
); diff --git a/src/components/experimentComponents/Circles.tsx b/src/components/experimentComponents/Circles.tsx index faa8e34..00a83fd 100644 --- a/src/components/experimentComponents/Circles.tsx +++ b/src/components/experimentComponents/Circles.tsx @@ -1,4 +1,4 @@ -import { useState, useRef, useEffect } from "react"; +import { useRef, useEffect } from "react"; import styles from "@/styles/Circles.module.css"; function Circles({ @@ -10,7 +10,7 @@ function Circles({ value: number; bsr: boolean; showResult: boolean; - chooseCircle: 0 | 1; + chooseCircle: "blue" | "red"; }) { const whiteCircle1 = useRef(null); const whiteCircle2 = useRef(null); @@ -38,7 +38,7 @@ function Circles({ const y = Math.sin(angle) * dist + 150; blackCross1.current!.style.display = `none`; blackCross2.current!.style.display = `none`; - if (chooseCircle === 0) { + if (chooseCircle === "blue") { blackCross1.current!.style.display = "block"; blackCross1.current!.style.top = `${y}px`; blackCross1.current!.style.left = `${x}px`; @@ -60,7 +60,7 @@ function Circles({ } } - function addCorrectMark(correct: number, number2?: number) { + function addCorrectMark(correct: "blue" | "red", number2?: number) { if (showResult) { if ( (chooseCircle === correct && number2 === undefined) || @@ -68,6 +68,7 @@ function Circles({ ) { return ` ${styles.correctAnswer}`; } else { + // return ` ${styles.inCorrectAnswer}`; return ` ${styles.invis}`; } } else { @@ -84,7 +85,7 @@ function Circles({ " " + styles.circle + addInvis(100) + - addCorrectMark(0) + addCorrectMark("blue") } > {bsr && ( @@ -106,7 +107,7 @@ function Circles({ styles.white + " " + styles.smallCircle + - addCorrectMark(0, 0) + addCorrectMark("blue", 0) } ref={whiteCircle1} >
@@ -120,7 +121,7 @@ function Circles({ styles.circle + " " + addInvis(0) + - addCorrectMark(1) + addCorrectMark("red") } >
diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index cfa0208..0c17dc0 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -53,9 +53,7 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { return ( <> -

- Çekilen toplar: -

+

Çekilen toplar:

))}
-
- + {treatment === "QSR" ? (
diff --git a/src/pages/admin/[id].tsx b/src/pages/admin/[id].tsx new file mode 100644 index 0000000..f0c9e30 --- /dev/null +++ b/src/pages/admin/[id].tsx @@ -0,0 +1,56 @@ +import { InferGetServerSidePropsType } from "next"; +import { GetServerSideProps } from "next"; +import { prisma } from "@/database"; +import { Participant,Round } from "@prisma/client"; + +import { Container, Table } from "@mantine/core"; + +export default function Home({ + data, +}: InferGetServerSidePropsType) { + const rows = data.map((participant) => ( + + {participant.name_surname} + { + participant.Round.reduce((acc,curr)=> + acc + curr.reward + ,0)} + + )); + return ( + + + + + + + + + {rows} +
Kişi adıKazanç
+
+ ); +} + +interface ParticipantWithRounds extends Participant{ + Round: Round[] +} + +export const getServerSideProps: GetServerSideProps<{ + data: ParticipantWithRounds[]; +}> = async ({ params }) => { + let relatedParticipants = await prisma.participant.findMany({ + where: { + sessionId: params?.id as string, + }, + include: { + Round: true + }}) as ParticipantWithRounds[]; + + console.log(relatedParticipants) + return { + props: { + data: relatedParticipants as ParticipantWithRounds[], + }, + }; +}; diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index be508d8..381da3d 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -1,52 +1,67 @@ -// import Head from "next/head"; - -// import { reducer, StateProvider } from "../../state"; -// import Experiment from "@/components/Experiment"; - import { InferGetServerSidePropsType } from "next"; import { GetServerSideProps } from "next"; import { prisma } from "@/database"; import { Session } from "@prisma/client"; -import { Table, Container } from "@mantine/core"; +import { useState } from "react"; + +import { Container, Button, Center } from "@mantine/core"; +import { DataTable } from "mantine-datatable"; +import { useRouter } from "next/router"; export default function Home({ data, }: InferGetServerSidePropsType) { - // console.log(data) + const [selectedSessions, setSelectedSessions] = useState([]); + const router = useRouter(); - // - // - const rows = data.map((session) => ( - - {session.name} - {session.start_time.toString()} - - )); + function downloadData() { + console.log("placeholder data download"); + } return ( - - {/* - Ekonomi Deneyi - - - - */} - - - - - - - - {rows} -
Oturum adıOturum zamanı
+ +
+ +
+ { + const d = new Date(session.start_time); + d.setHours(d.getHours() + 3); + return d.toLocaleString("tr-TR", { + year: "numeric", + month: "long", + day: "numeric", + weekday: "long", + hour: "2-digit", + minute: "2-digit", + }); + }, + }, + ]} + records={data} + selectedRecords={selectedSessions} + onSelectedRecordsChange={setSelectedSessions} + onRowClick={(session) => { + router.push(`./admin/${session.id}`); + }} + />
); } @@ -60,11 +75,6 @@ export const getServerSideProps: GetServerSideProps<{ start_time: JSON.parse(JSON.stringify(a?.start_time)), end_time: JSON.parse(JSON.stringify(a?.end_time)), })); - // sessionData.start_time = JSON.parse( - // JSON.stringify(sessionData?.start_time) - // ); - // sessionData.end_time = JSON.parse(JSON.stringify(sessionData?.end_time)); - // console.log(sessionData) return { props: { diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 645462c..7de3cc3 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -99,9 +99,9 @@ .embla__slide { flex: 0 0 100%; min-width: 0; -} +} */ -.embla__slide > ul > li { +/* .embla__slide > ul > li { list-style-position: inside; } */ From d203d20e83788d0838a89e0eeb19340232ac75be Mon Sep 17 00:00:00 2001 From: emrergin Date: Mon, 20 Mar 2023 15:40:49 +0300 Subject: [PATCH 04/24] admin page improvements --- README.md | 3 +- src/components/Experiment.tsx | 2 +- src/components/Intro.tsx | 23 ------- src/components/Intro2.tsx | 2 +- src/components/Round.tsx | 13 +--- .../experimentComponents/Drawing.tsx | 11 +--- src/pages/admin/index.tsx | 18 +++++- src/pages/api/round.ts | 60 ++++++++++++++++++- src/styles/Custom.module.css | 24 -------- src/utilities/functions.ts | 28 +++++++++ src/{state => utilities}/types.ts | 0 11 files changed, 108 insertions(+), 76 deletions(-) create mode 100644 src/utilities/functions.ts rename src/{state => utilities}/types.ts (100%) diff --git a/README.md b/README.md index 61089d2..dbcc73e 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,5 @@ Some introductory readings for the concepts. ## Sources - https://stackoverflow.com/questions/34189370/how-to-repeat-an-element-n-times-using-jsx-and-lodash -- https://blog.logrocket.com/effortless-database-schema-migration-prisma/ \ No newline at end of file +- https://blog.logrocket.com/effortless-database-schema-migration-prisma/ +- https://reacthustle.com/blog/flatten-object-javascript-typescript \ No newline at end of file diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index c5bd389..5556aad 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -11,7 +11,7 @@ import { useRef, useState } from "react"; import Round from "@/components/Round"; -import { Phase } from "@/state/types"; +import { Phase } from "@/utilities/types"; function shuffle(array: number[]) { let resArray = array; diff --git a/src/components/Intro.tsx b/src/components/Intro.tsx index b654f08..acb877d 100644 --- a/src/components/Intro.tsx +++ b/src/components/Intro.tsx @@ -18,33 +18,10 @@ function Intro({ async function assignName() { nameFunction(name); - // phaseFunction(Phase.Intro2); } return (
- {/*
    -
  • - Hoş geldiniz. Bu deneyde sizden bazı olasılıkları - değerlendirmenizi isteyeceğiz. -
  • -
  • - Oyunlarda kazancınızı "puan" cinsinden - hesaplayacağız. Toplam puanınızın parasal değerini ve ek - olarak bir katılım ücretini size deney sonunda nakit olarak - ödeyeceğiz. -
  • -
  • - Oyunları tamamladıktan sonra size dair bazı demografik - bilgileri sorduğumuz bir anket olacak. -
  • -
  • - Deneyden erken ayrılabilirsiniz. Bulunduğunuz sayfayı - değiştirmeniz ve yenilemeniz gibi durumlarda da deneyden - erken ayrılmış sayılacaksınız. Erken ayrılmanız durumunda o - zamana kadarki kararlarınız değerlendirilecek. -
  • -
*/} Hoş geldiniz. Bu deneyde sizden bazı olasılıkları diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index 38f83f8..7bb6319 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -5,7 +5,7 @@ import { useState, useCallback, useEffect } from "react"; import { Button, List } from "@mantine/core"; -import { Phase } from "@/state/types"; +import { Phase } from "@/utilities/types"; import Circles from "./experimentComponents/Circles"; diff --git a/src/components/Round.tsx b/src/components/Round.tsx index a55d0a5..92d2e2d 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -1,5 +1,5 @@ import { useState, useRef } from "react"; -import styles from "@/styles/Circles.module.css"; +// import styles from "@/styles/Circles.module.css"; import Slider from "./experimentComponents/Slider"; import Circles from "./experimentComponents/Circles"; import Drawing from "./experimentComponents/Drawing"; @@ -8,10 +8,8 @@ import customStyles from "@/styles/Custom.module.css"; import { Button } from "@mantine/core"; -import { Inter } from "next/font/google"; import { Round } from "@prisma/client"; -import { DrawingT, Phase } from "@/state/types"; -const inter = Inter({ subsets: ["latin"] }); +import { DrawingT, Phase } from "@/utilities/types"; interface SubTypeRound extends DrawingT { is_blue: boolean; @@ -163,13 +161,6 @@ function Round({
+ res: NextApiResponse[]> ) { if (req.method === "POST") { const { body } = req; @@ -14,5 +17,58 @@ export default async function handler( }); return res.status(200).json(newRound); } + if (req.method==="GET"){ + // console.log(req.query); + let relatedSessions:(string)[]=[]; + if(req.query!==undefined){ + if(typeof req.query.sessionId==="string"){ + relatedSessions = [req.query.sessionId]; + } + else if(typeof req.query.sessionId==="object"){ + relatedSessions = req.query.sessionId; + } + } + let allRounds: (Round & { + Participant: Participant & { + Session: Session; + }; + })[]; + if(relatedSessions.length===0){ + + allRounds = await prisma.round.findMany({include: { + Participant: { + include:{ + Session:true + } + } + }}); + }else{ + allRounds = await prisma.round.findMany({ + where:{ + Participant:{ + sessionId:{ + in: relatedSessions + } + } + }, + include: { + Participant: { + include:{ + Session:true + } + } + }}); + } + return res.status(200).json(allRounds.map(flattenRound)); + } res.end(); } + +function flattenRound(round:(Round & { + Participant: Participant & { + Session: Session; + }; +})){ + const {Participant,Session, ...rest} = {...round.Participant, ...round.Participant.Session,...round}; + return rest; +} diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 7de3cc3..21e2f23 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -89,30 +89,6 @@ line-height: 2ch; } -/* .embla { - overflow: hidden; - margin: 0px; -} -.embla__container { - display: flex; -} -.embla__slide { - flex: 0 0 100%; - min-width: 0; -} */ - -/* .embla__slide > ul > li { - list-style-position: inside; -} */ - -.navButton { - font-size: 24px; - padding: 8px 15px; -} - -/* .embla > * { - outline: 2px red solid; -} */ .reward { margin: 3ch; diff --git a/src/utilities/functions.ts b/src/utilities/functions.ts new file mode 100644 index 0000000..cf41b0d --- /dev/null +++ b/src/utilities/functions.ts @@ -0,0 +1,28 @@ +import { RoundToDownload } from "@/pages/api/round"; + +function arrayToCsv(data:RoundToDownload[],columnNames:string[]):string{ + let data2:(string[]|RoundToDownload)[] = [columnNames,...data]; + return data2.map(row => + Object.values(row) + .map(String) // convert every value to String + .map(v => v.replaceAll('"', '""')) // escape double colons + .map(v => `"${v}"`) // quote it + .join(',') // comma-separated + ).join('\r\n'); // rows starting on new lines + } + +function downloadBlob(content:string, filename:string, contentType:string) { + // Create a blob + var blob = new Blob([content], { type: contentType }); + var url = URL.createObjectURL(blob); + + // Create a link to download it + var pom = document.createElement('a'); + pom.href = url; + pom.setAttribute('download', filename); + pom.click(); +} + +export function downloadDataAsCsv(data:RoundToDownload[],columnNames:string[]){ + downloadBlob(arrayToCsv(data,columnNames), `${new Date()}.csv`, 'text/csv;charset=utf-8;') +} \ No newline at end of file diff --git a/src/state/types.ts b/src/utilities/types.ts similarity index 100% rename from src/state/types.ts rename to src/utilities/types.ts From b7701d32667ffcf076d641999b2b5e438334a6c3 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 25 Mar 2023 06:55:38 +0300 Subject: [PATCH 05/24] slider update --- exporting.sh | 4 +-- src/components/Experiment.tsx | 2 +- .../experimentComponents/Slider.tsx | 25 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/exporting.sh b/exporting.sh index 9a34e38..648ecc3 100644 --- a/exporting.sh +++ b/exporting.sh @@ -2,8 +2,8 @@ next build cp -r public .next/standalone cp -r ./.next/static .next/standalone/.next -cd /media/sf_linux_erisim/ +cd /media/sf_linux_erisim/ || return if [ -d standalone ]; then rm -r standalone; fi -cd /home/zulmet/odin1/belief-next/.next +cd /home/zulmet/odin1/belief-next/.next || return cp -r standalone /media/sf_linux_erisim/ \ No newline at end of file diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index 5556aad..ad19baf 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -34,7 +34,7 @@ function Experiment({ data }: { data: Session }) { setPhase(Phase.Intro2); } - const [phase, setPhase] = useState("INTRO"); + const [phase, setPhase] = useState("MAIN"); const randomizedDraws = useRef(shuffle(data.drawn_balls)); const [points, setPoints] = useState(0); diff --git a/src/components/experimentComponents/Slider.tsx b/src/components/experimentComponents/Slider.tsx index 8d32ebe..692290f 100644 --- a/src/components/experimentComponents/Slider.tsx +++ b/src/components/experimentComponents/Slider.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect } from "react"; +// import { useRef, useEffect } from "react"; import styles from "@/styles/Circles.module.css"; interface sliderProps { @@ -8,15 +8,17 @@ interface sliderProps { } function Slider({ updatingFunction, value, disabled = false }: sliderProps) { - const range = useRef(null); - const thumb = useRef(null); - const track = useRef(null); + // const range = useRef(null); + // const thumb = useRef(null); + // const track = useRef(null); - useEffect(() => { - thumb.current!.style.left = `${value}%`; - thumb.current!.style.transform = `translate(-${value}%, -50%)`; - track.current!.style.width = `${value}%`; - }, [value]); + // useEffect(() => { + // if(thumb.current!==null){ + // thumb.current!.style.left = `${value}%`; + // thumb.current!.style.transform = `translate(-${value}%, -50%)`; + // track.current!.style.width = `${value}%`; + // } + // }, [value]); return (
@@ -24,7 +26,6 @@ function Slider({ updatingFunction, value, disabled = false }: sliderProps) {
-
+
-
+
); From 3c746b0d9d879e8fe843f64747d4e207bb5b37b5 Mon Sep 17 00:00:00 2001 From: emrergin Date: Wed, 5 Apr 2023 16:31:59 +0300 Subject: [PATCH 06/24] admin authorization --- exporting.sh | 3 +- package-lock.json | 6 +++ package.json | 1 + src/components/Experiment.tsx | 3 +- src/components/Round.tsx | 6 +-- .../experimentComponents/Circles.tsx | 23 ++++------ .../experimentComponents/Drawing.tsx | 41 ++++++++++++++---- .../experimentComponents/Slider.tsx | 14 +------ src/pages/admin/index.tsx | 42 +++++++++++++++++-- src/pages/api/round.ts | 4 +- 10 files changed, 96 insertions(+), 47 deletions(-) diff --git a/exporting.sh b/exporting.sh index 648ecc3..4448d22 100644 --- a/exporting.sh +++ b/exporting.sh @@ -5,5 +5,6 @@ cp -r ./.next/static .next/standalone/.next cd /media/sf_linux_erisim/ || return if [ -d standalone ]; then rm -r standalone; fi cd /home/zulmet/odin1/belief-next/.next || return -cp -r standalone /media/sf_linux_erisim/ +tar cf belief.tar standalone +cp -r belief.tar /media/sf_linux_erisim/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 86d142a..79ff9bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.10.6", "@emotion/server": "^11.10.0", + "@formkit/auto-animate": "^1.0.0-beta.6", "@mantine/carousel": "^6.0.1", "@mantine/core": "^6.0.2", "@mantine/dates": "^6.0.1", @@ -364,6 +365,11 @@ "react-dom": ">=16.8.0" } }, + "node_modules/@formkit/auto-animate": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz", + "integrity": "sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", diff --git a/package.json b/package.json index b934fb0..802bfa6 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "@emotion/react": "^11.10.6", "@emotion/server": "^11.10.0", + "@formkit/auto-animate": "^1.0.0-beta.6", "@mantine/carousel": "^6.0.1", "@mantine/core": "^6.0.2", "@mantine/dates": "^6.0.1", diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index ad19baf..a51b21e 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -34,7 +34,8 @@ function Experiment({ data }: { data: Session }) { setPhase(Phase.Intro2); } - const [phase, setPhase] = useState("MAIN"); + const [phase, setPhase] = useState("INTRO"); + // const [phase, setPhase] = useState("MAIN"); const randomizedDraws = useRef(shuffle(data.drawn_balls)); const [points, setPoints] = useState(0); diff --git a/src/components/Round.tsx b/src/components/Round.tsx index 92d2e2d..67625f3 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -65,7 +65,6 @@ function Round({ } else { nextRound(); } - // console.log("placeholder, nextSubPhase - Treatment.tsx"); } function endDrawing(drawing: DrawingT) { @@ -94,11 +93,8 @@ function Round({ function nextRound() { const lastRound: Omit = { ...(roundData.current as SubTypeRound), - // decision_time: 0, participantId: participantId, - // id: crypto.randomUUID(), chosen_probability: 100 - redRatio, - // is_blue: selectedBag===0, reward: calculatePointsForRound(), round: currentRound, }; @@ -162,7 +158,7 @@ function Round({ diff --git a/src/components/experimentComponents/Circles.tsx b/src/components/experimentComponents/Circles.tsx index 00a83fd..a8398ba 100644 --- a/src/components/experimentComponents/Circles.tsx +++ b/src/components/experimentComponents/Circles.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect } from "react"; +import { useRef } from "react"; import styles from "@/styles/Circles.module.css"; function Circles({ @@ -12,21 +12,14 @@ function Circles({ showResult: boolean; chooseCircle: "blue" | "red"; }) { - const whiteCircle1 = useRef(null); - const whiteCircle2 = useRef(null); const blackCross1 = useRef(null); const blackCross2 = useRef(null); - useEffect(() => { - whiteCircle1.current!.style.width = `${value * 3}px`; - whiteCircle1.current!.style.height = `${value * 3}px`; - whiteCircle2.current!.style.width = `${300 - Number(value) * 3}px`; - whiteCircle2.current!.style.height = `${300 - Number(value) * 3}px`; - if (bsr) { - blackCross1.current!.style.display = `none`; - blackCross2.current!.style.display = `none`; - } - }, [value, bsr]); + + if (bsr && blackCross1.current!=null && blackCross2.current!==null && showResult) { + blackCross1.current!.style.display = `none`; + blackCross2.current!.style.display = `none`; + } function choosePoint() { if (!bsr) { @@ -109,7 +102,7 @@ function Circles({ styles.smallCircle + addCorrectMark("blue", 0) } - ref={whiteCircle1} + style={{width:`${value * 3}px`,height:`${value * 3}px`}} >
{bsr && (
{ + if(numberOfShownBalls b + 1); + }}, 1000); + + useEffect(() => { + interval.start(); + return interval.stop; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const parent = useRef(null); + + useEffect(() => { + parent.current && autoAnimate(parent.current) + }, [parent]); + + + + const draws = useRef( Array.from({ length: numberOfDraws }, () => Math.floor(Math.random() * 100) - ).map((num) => (num < numberofBlues ? 1 : 0)) - ); + ).map((num) => (num < numberofBlues ? 'blue' : 'red'))); function nextSubPhase() { nextFunction({ @@ -50,6 +72,7 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { return ( <> + {/* {numberOfShownBalls}-{numberOfDraws} */}

Çekilen toplar:

- {draws.current - .map((a) => (a === 1 ? "🔵" : "🔴")) + {draws.current.slice(0,numberOfShownBalls) + .map((a) => (a === 'blue' ? "🔵" : "🔴")) .map((e, i) => ( {e} @@ -70,6 +95,8 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { diff --git a/src/components/experimentComponents/Slider.tsx b/src/components/experimentComponents/Slider.tsx index 692290f..c1ff882 100644 --- a/src/components/experimentComponents/Slider.tsx +++ b/src/components/experimentComponents/Slider.tsx @@ -1,4 +1,3 @@ -// import { useRef, useEffect } from "react"; import styles from "@/styles/Circles.module.css"; interface sliderProps { @@ -7,18 +6,7 @@ interface sliderProps { disabled?: boolean; } -function Slider({ updatingFunction, value, disabled = false }: sliderProps) { - // const range = useRef(null); - // const thumb = useRef(null); - // const track = useRef(null); - - // useEffect(() => { - // if(thumb.current!==null){ - // thumb.current!.style.left = `${value}%`; - // thumb.current!.style.transform = `translate(-${value}%, -50%)`; - // track.current!.style.width = `${value}%`; - // } - // }, [value]); +function Slider({ updatingFunction, value, disabled }: sliderProps) { return (
diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 8430c28..7fa8174 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -3,35 +3,69 @@ import { GetServerSideProps } from "next"; import { prisma } from "@/database"; import { Session } from "@prisma/client"; -import { useState } from "react"; +import { useState,useEffect } from "react"; -import { Container, Button, Center } from "@mantine/core"; +import { Container, Button, Center,Modal,TextInput } from "@mantine/core"; import { DataTable } from "mantine-datatable"; import { useRouter } from "next/router"; import { downloadDataAsCsv } from "@/utilities/functions"; + +import { useDisclosure,useLocalStorage } from '@mantine/hooks'; + export default function Home({ data, }: InferGetServerSidePropsType) { const [selectedSessions, setSelectedSessions] = useState([]); const router = useRouter(); + const [pass, setPass] = useLocalStorage({ key: 'pass', defaultValue: '' }); + const [opened, { open, close }] = useDisclosure(false); + + async function downloadData(listOfSessions:string[]=selectedSessions.map(a=>a.id)) { let res =""; if(data.length>selectedSessions.length){ res = "?" + Object.entries(listOfSessions).map(([k, v]) => `sessionId=${v}`).join("&"); } + console.log(pass); const respond = await fetch("/belief/api/round"+res, { method: "GET", + headers: { Authorization: pass }, }); - + const columnNames = ["id","name_surname","sessionId","age","gpa","sex","dep","num_of_econ","diff","sure","gps_risk_willingness","gps_future_benefit","gps_punish_self","gps_punish_other","gps_d1","gps_d2","gps_d3","gps_d4","gps_d5","gps_stair_risk","gps_gift","gps_donation","gps_stair_patience","start_time","end_time","name","location","num_of_blue_a","num_of_blue_b","treatment","drawn_balls","prior","decision_time","chosen_probability","is_blue","first_draw_blue","second_draw_blue","third_draw_blue","fourth_draw_blue","fifth_draw_blue","sixth_draw_blue","round","reward","participantId"]; - + downloadDataAsCsv(await respond.json(),columnNames); } + + + + useEffect(()=>{ + if (pass===null || pass===""){ + open(); + }else{ + close(); + } + },[open,close,pass]); return ( + + setPass(event.currentTarget.value)} + /> + +
- + {treatment === "QSR" ? (
diff --git a/src/components/Round.tsx b/src/components/Round.tsx index 67625f3..3470494 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -158,7 +158,11 @@ function Round({ diff --git a/src/components/experimentComponents/Circles.tsx b/src/components/experimentComponents/Circles.tsx index a8398ba..d30fba0 100644 --- a/src/components/experimentComponents/Circles.tsx +++ b/src/components/experimentComponents/Circles.tsx @@ -15,8 +15,12 @@ function Circles({ const blackCross1 = useRef(null); const blackCross2 = useRef(null); - - if (bsr && blackCross1.current!=null && blackCross2.current!==null && showResult) { + if ( + bsr && + blackCross1.current != null && + blackCross2.current !== null && + showResult + ) { blackCross1.current!.style.display = `none`; blackCross2.current!.style.display = `none`; } @@ -102,7 +106,10 @@ function Circles({ styles.smallCircle + addCorrectMark("blue", 0) } - style={{width:`${value * 3}px`,height:`${value * 3}px`}} + style={{ + width: `${value * 3}px`, + height: `${value * 3}px`, + }} >
{bsr && (
{ - if(numberOfShownBalls b + 1); - }}, 1000); + } + }, 1000); useEffect(() => { interval.start(); return interval.stop; - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const parent = useRef(null); useEffect(() => { - parent.current && autoAnimate(parent.current) + parent.current && autoAnimate(parent.current); }, [parent]); - - const draws = useRef( Array.from({ length: numberOfDraws }, () => Math.floor(Math.random() * 100) - ).map((num) => (num < numberofBlues ? 'blue' : 'red'))); + ).map((num) => (num < numberofBlues ? "blue" : "red")) + ); function nextSubPhase() { nextFunction({ @@ -72,7 +70,7 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { return ( <> - {/* {numberOfShownBalls}-{numberOfDraws} */} + {/* {numberOfShownBalls}-{numberOfDraws} */}

Çekilen toplar:

- {draws.current.slice(0,numberOfShownBalls) - .map((a) => (a === 'blue' ? "🔵" : "🔴")) + {draws.current + .slice(0, numberOfShownBalls) + .map((a) => (a === "blue" ? "🔵" : "🔴")) .map((e, i) => ( {e} @@ -95,8 +94,8 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { diff --git a/src/components/experimentComponents/Slider.tsx b/src/components/experimentComponents/Slider.tsx index c1ff882..346cf73 100644 --- a/src/components/experimentComponents/Slider.tsx +++ b/src/components/experimentComponents/Slider.tsx @@ -7,7 +7,6 @@ interface sliderProps { } function Slider({ updatingFunction, value, disabled }: sliderProps) { - return (
@@ -22,9 +21,18 @@ function Slider({ updatingFunction, value, disabled }: sliderProps) { disabled={disabled} />
-
+
-
+
); diff --git a/src/pages/admin/[id].tsx b/src/pages/admin/[id].tsx index f0c9e30..85c5b3b 100644 --- a/src/pages/admin/[id].tsx +++ b/src/pages/admin/[id].tsx @@ -1,7 +1,7 @@ import { InferGetServerSidePropsType } from "next"; import { GetServerSideProps } from "next"; import { prisma } from "@/database"; -import { Participant,Round } from "@prisma/client"; +import { Participant, Round } from "@prisma/client"; import { Container, Table } from "@mantine/core"; @@ -11,15 +11,14 @@ export default function Home({ const rows = data.map((participant) => ( {participant.name_surname} - { - participant.Round.reduce((acc,curr)=> - acc + curr.reward - ,0)} + + {participant.Round.reduce((acc, curr) => acc + curr.reward, 0)} + )); return ( - +
@@ -32,22 +31,23 @@ export default function Home({ ); } -interface ParticipantWithRounds extends Participant{ - Round: Round[] +interface ParticipantWithRounds extends Participant { + Round: Round[]; } export const getServerSideProps: GetServerSideProps<{ data: ParticipantWithRounds[]; }> = async ({ params }) => { - let relatedParticipants = await prisma.participant.findMany({ - where: { - sessionId: params?.id as string, - }, - include: { - Round: true - }}) as ParticipantWithRounds[]; + let relatedParticipants = (await prisma.participant.findMany({ + where: { + sessionId: params?.id as string, + }, + include: { + Round: true, + }, + })) as ParticipantWithRounds[]; - console.log(relatedParticipants) + console.log(relatedParticipants); return { props: { data: relatedParticipants as ParticipantWithRounds[], diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 7fa8174..da874ed 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -3,15 +3,14 @@ import { GetServerSideProps } from "next"; import { prisma } from "@/database"; import { Session } from "@prisma/client"; -import { useState,useEffect } from "react"; +import { useState, useEffect } from "react"; -import { Container, Button, Center,Modal,TextInput } from "@mantine/core"; +import { Container, Button, Center, Modal, TextInput } from "@mantine/core"; import { DataTable } from "mantine-datatable"; import { useRouter } from "next/router"; import { downloadDataAsCsv } from "@/utilities/functions"; - -import { useDisclosure,useLocalStorage } from '@mantine/hooks'; +import { useDisclosure, useLocalStorage } from "@mantine/hooks"; export default function Home({ data, @@ -19,61 +18,116 @@ export default function Home({ const [selectedSessions, setSelectedSessions] = useState([]); const router = useRouter(); - const [pass, setPass] = useLocalStorage({ key: 'pass', defaultValue: '' }); + const [pass, setPass] = useLocalStorage({ key: "pass", defaultValue: "" }); const [opened, { open, close }] = useDisclosure(false); - - async function downloadData(listOfSessions:string[]=selectedSessions.map(a=>a.id)) { - let res =""; - if(data.length>selectedSessions.length){ - res = "?" + Object.entries(listOfSessions).map(([k, v]) => `sessionId=${v}`).join("&"); + async function downloadData( + listOfSessions: string[] = selectedSessions.map((a) => a.id) + ) { + let res = ""; + if (data.length > selectedSessions.length) { + res = + "?" + + Object.entries(listOfSessions) + .map(([k, v]) => `sessionId=${v}`) + .join("&"); } console.log(pass); - const respond = await fetch("/belief/api/round"+res, { + const respond = await fetch("/belief/api/round" + res, { method: "GET", headers: { Authorization: pass }, }); - - const columnNames = ["id","name_surname","sessionId","age","gpa","sex","dep","num_of_econ","diff","sure","gps_risk_willingness","gps_future_benefit","gps_punish_self","gps_punish_other","gps_d1","gps_d2","gps_d3","gps_d4","gps_d5","gps_stair_risk","gps_gift","gps_donation","gps_stair_patience","start_time","end_time","name","location","num_of_blue_a","num_of_blue_b","treatment","drawn_balls","prior","decision_time","chosen_probability","is_blue","first_draw_blue","second_draw_blue","third_draw_blue","fourth_draw_blue","fifth_draw_blue","sixth_draw_blue","round","reward","participantId"]; - - downloadDataAsCsv(await respond.json(),columnNames); - } - + const columnNames = [ + "id", + "name_surname", + "sessionId", + "age", + "gpa", + "sex", + "dep", + "num_of_econ", + "diff", + "sure", + "gps_risk_willingness", + "gps_future_benefit", + "gps_punish_self", + "gps_punish_other", + "gps_d1", + "gps_d2", + "gps_d3", + "gps_d4", + "gps_d5", + "gps_stair_risk", + "gps_gift", + "gps_donation", + "gps_stair_patience", + "start_time", + "end_time", + "name", + "location", + "num_of_blue_a", + "num_of_blue_b", + "treatment", + "drawn_balls", + "prior", + "decision_time", + "chosen_probability", + "is_blue", + "first_draw_blue", + "second_draw_blue", + "third_draw_blue", + "fourth_draw_blue", + "fifth_draw_blue", + "sixth_draw_blue", + "round", + "reward", + "participantId", + ]; + + downloadDataAsCsv(await respond.json(), columnNames); + } - useEffect(()=>{ - if (pass===null || pass===""){ + useEffect(() => { + if (pass === null || pass === "") { open(); - }else{ + } else { close(); } - },[open,close,pass]); + }, [open, close, pass]); return ( - - setPass(event.currentTarget.value)} - /> - - + + setPass(event.currentTarget.value)} + /> + +
[]> + res: NextApiResponse< + Round | Omit[] + > ) { if (req.method === "POST") { const { body } = req; @@ -17,17 +18,16 @@ export default async function handler( }); return res.status(200).json(newRound); } - if (req.method==="GET"){ - if(req.headers?.authorization!==process.env.ADMIN_PASS){ + if (req.method === "GET") { + if (req.headers?.authorization !== process.env.ADMIN_PASS) { return res.status(401).json([]); } - let relatedSessions:(string)[]=[]; - if(req.query!==undefined){ - if(typeof req.query.sessionId==="string"){ - relatedSessions = [req.query.sessionId]; - } - else if(typeof req.query.sessionId==="object"){ - relatedSessions = req.query.sessionId; + let relatedSessions: string[] = []; + if (req.query !== undefined) { + if (typeof req.query.sessionId === "string") { + relatedSessions = [req.query.sessionId]; + } else if (typeof req.query.sessionId === "object") { + relatedSessions = req.query.sessionId; } } let allRounds: (Round & { @@ -35,42 +35,50 @@ export default async function handler( Session: Session; }; })[]; - if(relatedSessions.length===0){ - - allRounds = await prisma.round.findMany({include: { - Participant: { - include:{ - Session:true - } - } - }}); - }else{ + if (relatedSessions.length === 0) { allRounds = await prisma.round.findMany({ - where:{ - Participant:{ - sessionId:{ - in: relatedSessions - } - } + include: { + Participant: { + include: { + Session: true, + }, + }, + }, + }); + } else { + allRounds = await prisma.round.findMany({ + where: { + Participant: { + sessionId: { + in: relatedSessions, + }, + }, }, include: { - Participant: { - include:{ - Session:true - } - } - }}); + Participant: { + include: { + Session: true, + }, + }, + }, + }); } return res.status(200).json(allRounds.map(flattenRound)); } res.end(); } -function flattenRound(round:(Round & { - Participant: Participant & { - Session: Session; - }; -})){ - const {Participant,Session, ...rest} = {...round.Participant, ...round.Participant.Session,...round}; +function flattenRound( + round: Round & { + Participant: Participant & { + Session: Session; + }; + } +) { + const { Participant, Session, ...rest } = { + ...round.Participant, + ...round.Participant.Session, + ...round, + }; return rest; } diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 21e2f23..81e7ff6 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -89,7 +89,6 @@ line-height: 2ch; } - .reward { margin: 3ch; text-align: center; diff --git a/src/utilities/functions.ts b/src/utilities/functions.ts index cf41b0d..b4f18ef 100644 --- a/src/utilities/functions.ts +++ b/src/utilities/functions.ts @@ -1,28 +1,38 @@ import { RoundToDownload } from "@/pages/api/round"; -function arrayToCsv(data:RoundToDownload[],columnNames:string[]):string{ - let data2:(string[]|RoundToDownload)[] = [columnNames,...data]; - return data2.map(row => - Object.values(row) - .map(String) // convert every value to String - .map(v => v.replaceAll('"', '""')) // escape double colons - .map(v => `"${v}"`) // quote it - .join(',') // comma-separated - ).join('\r\n'); // rows starting on new lines - } +function arrayToCsv(data: RoundToDownload[], columnNames: string[]): string { + let data2: (string[] | RoundToDownload)[] = [columnNames, ...data]; + return data2 + .map( + (row) => + Object.values(row) + .map(String) // convert every value to String + .map((v) => v.replaceAll('"', '""')) // escape double colons + .map((v) => `"${v}"`) // quote it + .join(",") // comma-separated + ) + .join("\r\n"); // rows starting on new lines +} -function downloadBlob(content:string, filename:string, contentType:string) { - // Create a blob - var blob = new Blob([content], { type: contentType }); - var url = URL.createObjectURL(blob); +function downloadBlob(content: string, filename: string, contentType: string) { + // Create a blob + var blob = new Blob([content], { type: contentType }); + var url = URL.createObjectURL(blob); - // Create a link to download it - var pom = document.createElement('a'); - pom.href = url; - pom.setAttribute('download', filename); - pom.click(); + // Create a link to download it + var pom = document.createElement("a"); + pom.href = url; + pom.setAttribute("download", filename); + pom.click(); } -export function downloadDataAsCsv(data:RoundToDownload[],columnNames:string[]){ - downloadBlob(arrayToCsv(data,columnNames), `${new Date()}.csv`, 'text/csv;charset=utf-8;') -} \ No newline at end of file +export function downloadDataAsCsv( + data: RoundToDownload[], + columnNames: string[] +) { + downloadBlob( + arrayToCsv(data, columnNames), + `${new Date()}.csv`, + "text/csv;charset=utf-8;" + ); +} From 3cde5795e8c5b5ea14dc6223256c3495ba04a6c7 Mon Sep 17 00:00:00 2001 From: emrergin Date: Thu, 6 Apr 2023 00:20:56 +0300 Subject: [PATCH 08/24] more dynamic routes --- exporting.sh | 4 ++-- next.config.js | 5 ++++- src/components/Experiment.tsx | 2 +- src/components/Round.tsx | 2 +- src/pages/admin/index.tsx | 16 ++++++++++------ 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/exporting.sh b/exporting.sh index 4448d22..db344a8 100644 --- a/exporting.sh +++ b/exporting.sh @@ -5,6 +5,6 @@ cp -r ./.next/static .next/standalone/.next cd /media/sf_linux_erisim/ || return if [ -d standalone ]; then rm -r standalone; fi cd /home/zulmet/odin1/belief-next/.next || return -tar cf belief.tar standalone -cp -r belief.tar /media/sf_linux_erisim/ +tar cjf belief.tar.bz2 standalone +cp -r belief.tar.bz2 /media/sf_linux_erisim/ \ No newline at end of file diff --git a/next.config.js b/next.config.js index a0a7d51..af07656 100644 --- a/next.config.js +++ b/next.config.js @@ -1,8 +1,11 @@ +const isProd = process.env.NODE_ENV === 'production' + /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - basePath: '/belief', + // basePath: '/belief', output: 'standalone', + assetPrefix: isProd ? '/belief/' : undefined, }; module.exports = nextConfig; diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index a51b21e..bd6a935 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -26,7 +26,7 @@ function Experiment({ data }: { data: Session }) { const [participant, setParticipant] = useState>({}); async function generateNewParticipant(name: string) { - const respond = await fetch("/belief/api/participant", { + const respond = await fetch("./api/participant", { method: "POST", body: JSON.stringify({ name_surname: name, sessionId: data.id }), }); diff --git a/src/components/Round.tsx b/src/components/Round.tsx index 3470494..9906891 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -84,7 +84,7 @@ function Round({ } async function generateNewRound(lastRound: Omit) { - const respond = await fetch("/belief/api/round", { + const respond = await fetch("./api/round", { method: "POST", body: JSON.stringify(lastRound), }); diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index da874ed..c2d8adb 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -3,7 +3,7 @@ import { GetServerSideProps } from "next"; import { prisma } from "@/database"; import { Session } from "@prisma/client"; -import { useState, useEffect } from "react"; +import { useState, useEffect,useRef } from "react"; import { Container, Button, Center, Modal, TextInput } from "@mantine/core"; import { DataTable } from "mantine-datatable"; @@ -17,6 +17,7 @@ export default function Home({ }: InferGetServerSidePropsType) { const [selectedSessions, setSelectedSessions] = useState([]); const router = useRouter(); + const passRef = useRef(null); const [pass, setPass] = useLocalStorage({ key: "pass", defaultValue: "" }); const [opened, { open, close }] = useDisclosure(false); @@ -33,7 +34,7 @@ export default function Home({ .join("&"); } console.log(pass); - const respond = await fetch("/belief/api/round" + res, { + const respond = await fetch("../api/round" + res, { method: "GET", headers: { Authorization: pass }, }); @@ -103,8 +104,7 @@ export default function Home({ placeholder="Admin password" label="password" withAsterisk - value={pass} - onChange={(event) => setPass(event.currentTarget.value)} + ref={passRef} /> From 179a306c5ba0ac3c7d9045a7961d0c3ad214bdee Mon Sep 17 00:00:00 2001 From: emrergin Date: Mon, 15 May 2023 23:55:02 +0300 Subject: [PATCH 09/24] minor corrections all over the place --- README.md | 8 +- src/components/Experiment.tsx | 9 +- src/components/Intro2.tsx | 18 +- src/components/Round.tsx | 12 +- .../experimentComponents/BagHolder.tsx | 6 +- .../experimentComponents/Circles.tsx | 192 ++++++++---------- .../experimentComponents/Drawing.tsx | 10 +- src/pages/_app.tsx | 14 +- src/pages/admin/index.tsx | 8 +- src/pages/index.tsx | 8 +- src/styles/Circles.module.css | 18 +- src/styles/Custom.module.css | 4 +- src/styles/Home.module.css | 11 +- src/styles/globals.css | 26 +++ src/utilities/functions.ts | 9 + 15 files changed, 201 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index dbcc73e..3a2fc08 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,10 @@ Some introductory readings for the concepts. ## Sources - https://stackoverflow.com/questions/34189370/how-to-repeat-an-element-n-times-using-jsx-and-lodash - https://blog.logrocket.com/effortless-database-schema-migration-prisma/ -- https://reacthustle.com/blog/flatten-object-javascript-typescript \ No newline at end of file +- https://reacthustle.com/blog/flatten-object-javascript-typescript + +## What I learned +- This is the first Next.js app I completed. +- This is the first time I am using Prisma, and also PostgreSQL. +- For autoanimate to work as expected, the parent element needs to have a specified width. +- My first use case of Intl.ListFormat. \ No newline at end of file diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index bd6a935..52382f8 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -6,13 +6,15 @@ import Intro2 from "@/components/Intro2"; import Footer from "./Footer"; -import { Participant, Session } from "@prisma/client"; +import { Participant } from "@prisma/client"; import { useRef, useState } from "react"; import Round from "@/components/Round"; import { Phase } from "@/utilities/types"; +import { SessionType } from "@/pages"; + function shuffle(array: number[]) { let resArray = array; for (let i = resArray.length - 1; i > 0; i--) { @@ -22,7 +24,7 @@ function shuffle(array: number[]) { return resArray; } -function Experiment({ data }: { data: Session }) { +function Experiment({ data }: { data: SessionType }) { const [participant, setParticipant] = useState>({}); async function generateNewParticipant(name: string) { @@ -51,6 +53,7 @@ function Experiment({ data }: { data: Session }) { @@ -64,7 +67,7 @@ function Experiment({ data }: { data: Session }) { bBlue={data.num_of_blue_b} phaseFunction={setPhase} pointFunction={setPoints} - participantId={participant.id as string} + participantId={participant?.id||"no-id-given"} /> )} {phase === "END" && ( diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index c48ac0e..df7945b 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -7,21 +7,25 @@ import { Button, List } from "@mantine/core"; import { Phase } from "@/utilities/types"; + import Circles from "./experimentComponents/Circles"; import { Carousel, Embla } from "@mantine/carousel"; import Slider from "./experimentComponents/Slider"; import BagHolder from "./experimentComponents/BagHolder"; +import { getDiceText } from "@/utilities/functions"; function Intro2({ aBlue, bBlue, + priors, treatment, phaseFunction, }: { aBlue: number; bBlue: number; + priors: [number, number]; treatment: string; phaseFunction: (p: Phase) => void; }) { @@ -30,6 +34,7 @@ function Intro2({ const [showNextPhase, setShowNextPhase] = useState(false); const [embla, setEmbla] = useState(null); + const diceText=getDiceText(priors); const scrollPrev = useCallback(() => { if (!embla) { @@ -57,7 +62,7 @@ function Intro2({ <> @@ -92,7 +98,7 @@ function Intro2({ düşünebilirsiniz. - Zar sonucu 1, 2 veya 3 ise, çekiliş daha + Zar sonucu {diceText[0]} ise, çekiliş daha fazla mavi bilye içeren{" "} Mavi torba @@ -100,7 +106,7 @@ function Intro2({ dan yapılır. - Zar sonucu 4, 5 veya 6 ise, çekiliş daha + Zar sonucu {diceText[1]} ise, çekiliş daha fazla kırmızı bilye içeren{" "} Kırmızı torba @@ -113,7 +119,7 @@ function Intro2({ - + @@ -334,7 +340,7 @@ function Intro2({ - {slideIndex + 1} + {/* {slideIndex + 1} */} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index bd018f8..5ece6e8 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,16 +1,11 @@ -// import "@/styles/globals.css"; -// import type { AppProps } from "next/app"; - -// export default function App({ Component, pageProps }: AppProps) { -// return ; -// } - import { AppProps } from "next/app"; import Head from "next/head"; import { MantineProvider } from "@mantine/core"; +import "@/styles/globals.css"; export default function App(props: AppProps) { const { Component, pageProps } = props; + const isProd = process.env.NODE_ENV === "production"; return ( <> @@ -24,7 +19,10 @@ export default function App(props: AppProps) { name="viewport" content="minimum-scale=1,width=device-width, initial-scale=1" /> - + ) { const [selectedSessions, setSelectedSessions] = useState([]); const router = useRouter(); - const passRef = useRef(null); + const passRef = useRef(null); const [pass, setPass] = useLocalStorage({ key: "pass", defaultValue: "" }); const [opened, { open, close }] = useDisclosure(false); @@ -113,8 +113,8 @@ export default function Home({ display: "block", }} onClick={() => { - setPass(passRef?.current?.value||""); - if(passRef?.current?.value!==""){ + setPass(passRef?.current?.value || ""); + if (passRef?.current?.value !== "") { close(); } }} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6ff8381..0bcb700 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -15,6 +15,10 @@ export default function Home({ return ; } +export interface SessionType extends Omit { + prior: [number,number] +} + const defaultSession: Omit = { // id: 'placeholderSession', start_time: new Date(), @@ -29,7 +33,7 @@ const defaultSession: Omit = { }; export const getServerSideProps: GetServerSideProps<{ - data: Session; + data: SessionType; }> = async () => { let sessionData = await prisma.session.findFirst(); @@ -45,7 +49,7 @@ export const getServerSideProps: GetServerSideProps<{ return { props: { - data: sessionData as Session, + data: sessionData as SessionType, }, }; }; diff --git a/src/styles/Circles.module.css b/src/styles/Circles.module.css index 3c65523..df7db88 100644 --- a/src/styles/Circles.module.css +++ b/src/styles/Circles.module.css @@ -5,8 +5,8 @@ } /* .circleHolder>*{ - outline: red 2px solid; - } */ + outline: green 2px solid; +} */ .padding-left { padding-left: 2vw; @@ -89,7 +89,7 @@ .smallestCircle:after { content: "\00d7"; - font-size: 30px; + font-size: 1.9rem; top: 50%; left: 10%; display: inline-block; @@ -162,10 +162,18 @@ button.exp { /* display: none; */ } -.correctAnswer { +/* .correctAnswer { outline: 5px gold solid; -} +} */ .inCorrectAnswer { display: none; } + +.valueBox { + position: absolute; + bottom: -40px; + left: 150px; + transform: translateX(-50%); + font-size: 20px; +} diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 81e7ff6..3898d02 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -29,8 +29,8 @@ } .nameEntry > button { - font-size: 24px; - padding: 8px 15px; + font-size: 1.65rem; + padding: 0.6rem 1.1rem; } .debug { diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css index 28d6780..bc48390 100644 --- a/src/styles/Home.module.css +++ b/src/styles/Home.module.css @@ -5,8 +5,13 @@ align-items: center; padding: 6rem; min-height: 100vh; + /* font-size: 14px; */ } +/* .main *{ + font-size: 14px; +} */ + .description { display: inherit; justify-content: inherit; @@ -51,13 +56,13 @@ border-radius: var(--border-radius); background: rgba(var(--card-rgb), 0); border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; + /* transition: background 200ms, border 200ms; */ } - +/* .card span { display: inline-block; transition: transform 200ms; -} +} */ .card h2 { font-weight: 600; diff --git a/src/styles/globals.css b/src/styles/globals.css index e6ccd0f..29952d7 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,6 +1,7 @@ :root { --max-width: 1100px; --border-radius: 12px; + font-size: 14px; --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace; @@ -82,6 +83,10 @@ margin: 0; } +html { + font-size: 14px; +} + html, body { max-width: 100vw; @@ -108,3 +113,24 @@ a { color-scheme: dark; } } + +/* @media (min-resolution: 120dpi) { + html { + transform-origin: top left;; + transform: scale(0.8); + } +} + +@media (min-resolution: 150dpi) { + html { + transform-origin: top left;; + transform: scale(0.64); + } +} + +@media (min-resolution: 180dpi) { + html { + transform-origin: top left;; + transform: scale(0.53); + } +} */ diff --git a/src/utilities/functions.ts b/src/utilities/functions.ts index b4f18ef..c6c80c7 100644 --- a/src/utilities/functions.ts +++ b/src/utilities/functions.ts @@ -36,3 +36,12 @@ export function downloadDataAsCsv( "text/csv;charset=utf-8;" ); } + +export function getDiceText(prior: [number, number]):[String,String] { + const formatter = new Intl.ListFormat('tr', { style: 'long', type: 'disjunction' }); + const allDice = ["1", "2", "3", "4", "5", "6"]; + return [ + formatter.format(allDice.slice(0, prior[0])), + formatter.format(allDice.slice(prior[1])), + ]; +} From c6416e293e77c1bab6dcc34ba4a5d5ed82cf5805 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 20 May 2023 12:06:11 +0300 Subject: [PATCH 10/24] more information on screen for participants --- README.md | 2 +- src/components/Experiment.tsx | 4 +- src/components/Round.tsx | 63 ++++++++++--------- .../experimentComponents/BagHolder.tsx | 10 +-- .../experimentComponents/Drawing.tsx | 18 +++--- src/styles/Custom.module.css | 1 + 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 3a2fc08..deade1b 100644 --- a/README.md +++ b/README.md @@ -30,4 +30,4 @@ Some introductory readings for the concepts. - This is the first Next.js app I completed. - This is the first time I am using Prisma, and also PostgreSQL. - For autoanimate to work as expected, the parent element needs to have a specified width. -- My first use case of Intl.ListFormat. \ No newline at end of file +- My first use case of ``Intl.ListFormat``. \ No newline at end of file diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index 52382f8..ee13187 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -25,7 +25,7 @@ function shuffle(array: number[]) { } function Experiment({ data }: { data: SessionType }) { - const [participant, setParticipant] = useState>({}); + const [participant, setParticipant] = useState({}); async function generateNewParticipant(name: string) { const respond = await fetch("./api/participant", { @@ -67,7 +67,7 @@ function Experiment({ data }: { data: SessionType }) { bBlue={data.num_of_blue_b} phaseFunction={setPhase} pointFunction={setPoints} - participantId={participant?.id||"no-id-given"} + participantId={"id" in participant? participant.id:"no-id-given"} /> )} {phase === "END" && ( diff --git a/src/components/Round.tsx b/src/components/Round.tsx index 72ead71..e187acd 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -127,55 +127,56 @@ function Round({ return (
- {subPhase === "drawing" && ( + {/* {subPhase === "drawing" && ( */} <> - - endDrawing(d)} - /> - - )} - {(subPhase === "input" || subPhase === "result") && ( - <> - */} + + endDrawing(d)} + fullView={subPhase === "drawing"} + /> + {/* + } */} + {subPhase==="input" && - {/*
*/} - } + {(subPhase==="input" || subPhase==="result") && - {/*
*/} + />} {subPhase === "result" && (
{`${calculatePointsForRound()} kazandınız.`}
)} - - + + } - )}
); } diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index f4f0255..d110837 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -2,7 +2,7 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; import { Text } from "@mantine/core"; -function BagHolder({ aBlue, bBlue, diceText }: { aBlue: number; bBlue: number; diceText:[String,String] }) { +function BagHolder({ aBlue, bBlue, diceText, showBalls=true }: { aBlue: number; bBlue: number; diceText:[String,String]; showBalls?:boolean }) { return (
@@ -13,14 +13,14 @@ function BagHolder({ aBlue, bBlue, diceText }: { aBlue: number; bBlue: number; d {100 - bBlue} adet{" "} kırmızı bilye -
+ {showBalls &&
{[...Array(bBlue)].map((e, i) => (
🔵
))} {[...Array(100 - bBlue)].map((e, i) => (
🔴
))} -
+
} Zar sonucu {diceText[0]} ise kullanılır.
@@ -32,14 +32,14 @@ function BagHolder({ aBlue, bBlue, diceText }: { aBlue: number; bBlue: number; d kırmızı bilye -
+ {showBalls &&
{[...Array(aBlue)].map((e, i) => (
🔵
))} {[...Array(100 - aBlue)].map((e, i) => (
🔴
))} -
+
} Zar sonucu {diceText[1]} ise kullanılır.
diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index 690d1ab..dbd2812 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -9,9 +9,10 @@ interface drawingProps { numberofBlues: number; numberOfDraws: number; nextFunction: (d: DrawingT) => void; + fullView?: boolean; } -function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { +function Drawing({ numberofBlues, numberOfDraws, nextFunction,fullView=true }: drawingProps) { const [numberOfShownBalls, setNumberOfShownBalls] = useState(-1); const interval = useInterval(() => { @@ -70,10 +71,13 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction }: drawingProps) { return ( <> {/* {numberOfShownBalls}-{numberOfDraws} */} -

Çekilen toplar:

-

- Bu turda {numberOfDraws} top çekilecek. -

+ {fullView && + <> +

Çekilen toplar:

+

+ Bu turda {numberOfDraws} top çekilecek. +

+ }
))}
- + } ); } diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 3898d02..1519030 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -92,6 +92,7 @@ .reward { margin: 3ch; text-align: center; + margin-top:5ch; } .footer { From b92accdf5cf62c3bae50d6366b0505ee836bad60 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 20 May 2023 13:12:51 +0300 Subject: [PATCH 11/24] removes night mode variables --- src/styles/globals.css | 65 +----------------------------------------- 1 file changed, 1 insertion(+), 64 deletions(-) diff --git a/src/styles/globals.css b/src/styles/globals.css index 29952d7..7e0c4d3 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -41,42 +41,6 @@ --card-border-rgb: 131, 134, 135; } -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient( - rgba(1, 65, 255, 0.4), - rgba(1, 65, 255, 0) - ); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - * { box-sizing: border-box; padding: 0; @@ -106,31 +70,4 @@ body { a { color: inherit; text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} - -/* @media (min-resolution: 120dpi) { - html { - transform-origin: top left;; - transform: scale(0.8); - } -} - -@media (min-resolution: 150dpi) { - html { - transform-origin: top left;; - transform: scale(0.64); - } -} - -@media (min-resolution: 180dpi) { - html { - transform-origin: top left;; - transform: scale(0.53); - } -} */ +} \ No newline at end of file From 100159bbb2f375d4f5ed143d54d920d4bbe4ecb8 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 20 May 2023 15:04:33 +0300 Subject: [PATCH 12/24] drawing ball bug is solved --- src/components/Round.tsx | 89 +++++++++---------- .../experimentComponents/Drawing.tsx | 13 ++- 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/components/Round.tsx b/src/components/Round.tsx index e187acd..c7ecaec 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -1,5 +1,4 @@ import { useState, useRef } from "react"; -// import styles from "@/styles/Circles.module.css"; import Slider from "./experimentComponents/Slider"; import Circles from "./experimentComponents/Circles"; import Drawing from "./experimentComponents/Drawing"; @@ -127,56 +126,50 @@ function Round({ return (
- {/* {subPhase === "drawing" && ( */} - <> - {/* {subPhase!=="result" && - <> */} - - endDrawing(d)} - fullView={subPhase === "drawing"} - /> - {/* - } */} - {subPhase==="input" && } - {(subPhase==="input" || subPhase==="result") && + + endDrawing(d)} + fullView={subPhase === "drawing"} + key={currentRound} + /> + {subPhase==="input" && } + {(subPhase==="input" || subPhase==="result") && } + + {subPhase === "result" && ( +
+ {`${calculatePointsForRound()} kazandınız.`} +
+ )} + {(subPhase==="input" || subPhase==="result") && + - } - + + } +
); } diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index dbd2812..f8f56c1 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -44,33 +44,32 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction,fullView=true }: d first_draw_blue: draws.current[0] === undefined ? null - : Boolean(draws.current[0]), + : draws.current[0]==="blue", second_draw_blue: draws.current[1] === undefined ? null - : Boolean(draws.current[1]), + : draws.current[1]==="blue", third_draw_blue: draws.current[2] === undefined ? null - : Boolean(draws.current[2]), + : draws.current[2]==="blue", fourth_draw_blue: draws.current[3] === undefined ? null - : Boolean(draws.current[3]), + : draws.current[3]==="blue", fifth_draw_blue: draws.current[4] === undefined ? null - : Boolean(draws.current[4]), + : draws.current[4]==="blue", sixth_draw_blue: draws.current[5] === undefined ? null - : Boolean(draws.current[5]), + : draws.current[5]==="blue", }); } return ( <> - {/* {numberOfShownBalls}-{numberOfDraws} */} {fullView && <>

Çekilen toplar:

From d89722d920f61371438fec4b302251e234129bcb Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 20 May 2023 16:13:22 +0300 Subject: [PATCH 13/24] added topbar component starter --- src/components/Experiment.tsx | 5 ++--- src/components/TopBar.tsx | 18 ++++++++++++++++++ src/styles/Custom.module.css | 15 +++++++++++++-- 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/components/TopBar.tsx diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index ee13187..4b65c98 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -3,6 +3,7 @@ import cStyles from "@/styles/Custom.module.css"; import Intro from "@/components/Intro"; import Intro2 from "@/components/Intro2"; +import TopBar from "@/components/TopBar"; import Footer from "./Footer"; @@ -43,9 +44,7 @@ function Experiment({ data }: { data: SessionType }) { return (
-

- {phase} - {data.treatment} -

+ {phase === "INTRO" && ( )} diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx new file mode 100644 index 0000000..1cbbc77 --- /dev/null +++ b/src/components/TopBar.tsx @@ -0,0 +1,18 @@ +import customStyles from "@/styles/Custom.module.css"; + +const phaseName = new Map(); +phaseName.set("INTRO","Giriş"); +phaseName.set("INTRO2","Giriş"); +phaseName.set("MAIN","Giriş"); +phaseName.set("END","Sonuç"); + +function TopBar({phase}:{phase:string}) { + + return ( +
+ {phaseName.get(phase)} +
+ ); +} + +export default TopBar; \ No newline at end of file diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 1519030..ea50629 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -33,10 +33,10 @@ padding: 0.6rem 1.1rem; } -.debug { +/* .debug { position: absolute; left: 5px; -} +} */ .ballText { text-align: center; @@ -115,3 +115,14 @@ .footer > a { color: rgb(47, 47, 203); } + +.topbar{ + position: fixed; + left: 0px; + top: 0px; + width: 100%; + background-color: rgb(226, 241, 247); + box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px; + margin-top: 0px; + padding:1ch 5ch; +} \ No newline at end of file From e6cee8d3fb8810b60db235cbd62cf6911ff9a06b Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 27 May 2023 14:34:05 +0300 Subject: [PATCH 14/24] corrections to intro screen --- src/components/Experiment.tsx | 8 +- src/components/Intro2.tsx | 161 +++++++++--------- src/components/Round.tsx | 49 +++--- src/components/TopBar.tsx | 19 +-- .../experimentComponents/BagHolder.tsx | 48 ++++-- .../experimentComponents/Drawing.tsx | 52 +++--- src/pages/admin/index.tsx | 19 ++- src/pages/index.tsx | 4 +- src/styles/Custom.module.css | 8 +- src/styles/globals.css | 2 +- src/utilities/functions.ts | 17 +- 11 files changed, 215 insertions(+), 172 deletions(-) diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index 4b65c98..9f2c7fc 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -26,7 +26,7 @@ function shuffle(array: number[]) { } function Experiment({ data }: { data: SessionType }) { - const [participant, setParticipant] = useState({}); + const [participant, setParticipant] = useState({}); async function generateNewParticipant(name: string) { const respond = await fetch("./api/participant", { @@ -44,7 +44,7 @@ function Experiment({ data }: { data: SessionType }) { return (
- + {phase === "INTRO" && ( )} @@ -66,7 +66,9 @@ function Experiment({ data }: { data: SessionType }) { bBlue={data.num_of_blue_b} phaseFunction={setPhase} pointFunction={setPoints} - participantId={"id" in participant? participant.id:"no-id-given"} + participantId={ + "id" in participant ? participant.id : "no-id-given" + } /> )} {phase === "END" && ( diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index df7945b..8dc166c 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -7,7 +7,6 @@ import { Button, List } from "@mantine/core"; import { Phase } from "@/utilities/types"; - import Circles from "./experimentComponents/Circles"; import { Carousel, Embla } from "@mantine/carousel"; @@ -34,7 +33,7 @@ function Intro2({ const [showNextPhase, setShowNextPhase] = useState(false); const [embla, setEmbla] = useState(null); - const diceText=getDiceText(priors); + const diceText = getDiceText(priors); const scrollPrev = useCallback(() => { if (!embla) { @@ -119,7 +118,15 @@ function Intro2({ - + +
+ Renkli Bilyeler: Her iki torbanın içindeki + bilyeleri yukarıda görebilirsiniz. +
@@ -127,21 +134,15 @@ function Intro2({ Kullanılan Torba: Zar atışının sonucu size önceden söylenmeyecek, bu nedenle çekiliş için hangi torbanın kullanıldığını bilemezsiniz. Zar, her turda - her kişi için ayrı ayrı atılır, bu nedenle sizin - için kullanılan torba deneye katılan başka bir kişi - için kullanılan torbayla aynı olabilir veya - olmayabilir. + her kişi için ayrı ayrı atılır. Çekilişler kişiye özeldir: Bilgisayar zar atışı sonrası kullanılacak torbayı belirlediğinde, o torbadan rastgele çekilecek bir veya daha fazla - bilye gösterilebilir. Bu çekilişler size sizin - gördüğünüz değerler için hangi torbanın kullanıldığı - hakkında bilgi verebilse de, kullanılan torba - kişiden kişiye değişebileceğinden, başkaları için - kullanılan torba hakkında herhangi bir bilgi - sağlamaz. + bilye gösterilebilir. Bu çekilişler size o turda + hangi torbanın kullanıldığı hakkında bilgi + verebilir. Çekilişler birbirinden bağımsızdır: Bazı @@ -156,29 +157,16 @@ function Intro2({ bilyelerin sayıları ve renkleri bütün çekilişlerden önce her zaman aynı olacak. + + Her çekiliş sonrası bilye torbaya geri konur:{" "} + Çekilen bilye, her çekilişten sonra torbaya geri + konmuş gibi olur. + - - Çekilişler birbirinden bağımsızdır: Bazı - turlarda aynı torbadan birden fazla çekiliş - görebilirsiniz. Bunların sonucunu çekiliş sırasıyla - göreceksiniz. Çekilişler bağımsız olarak yapılacak, - yani sanki torbayı sallayacak, içinden rastgele bir - bilye seçecek, bilyeyi size gösterecek, torbaya geri - koyacak ve rastgele başka bir bilye çekmeden önce - torbayı tekrar karıştıracakmışız gibi - düşünebilirsiniz. - - - Her çekiliş sonrası bilye torbaya geri konur:{" "} - Çekilen bilye, her çekilişten sonra torbaya geri - konmuş gibi olur. Yani bir torbanın içindeki - bilyelerin sayıları ve renkleri bütün çekilişlerden - önce her zaman aynı olacak. - Çekiliş sonuçlarını gördükten sonra, kullanılan torbanın Kırmızı torba olma ihtimalinin{" "} @@ -188,19 +176,11 @@ function Intro2({ karar vermelisiniz. - O tur, hiç çekiliş yapılmayan bir tursa, kararınızı - tamamen zar atışının kullanılan torbayı nasıl - belirlendiğine dayandırmanız gerekir. Aksi takdirde, - torbaların içeriğini göz önünde bulundurarak hem + Torbaların içeriğini göz önünde bulundurarak, hem torbanın nasıl seçildiğine hem de alakalı çekiliş veya çekilişlerin sonucuna ilişkin bilgileri kullanabilirsiniz. - - - - - Şayet kararınız 0 ise, bu Kırmızı torbanın kullanılma ihtimalinin olmadığını düşündüğünüz @@ -215,48 +195,44 @@ function Intro2({ olduğunu düşünüyorsanız 50'nin altında bir sayı seçin. - - { - setSliderValue(Number(event.target.value)); - }} - /> -
- Sizce, seçilen torbanın{" "} - - kırmızı torba - {" "} - olma ihtimali: Yüzde {sliderValue}. -
-
- Sizce, seçilen torbanın{" "} - mavi torba{" "} - olma ihtimali: Yüzde {100 - sliderValue}. -
{treatment === "QSR" ? (
- + - Burada kaydırıcıyı sağa ya da sola - sürükleyerek size göre Kırmızı torbanın - kullanılmış olma ihtimalini bildireceksiniz. - Bu esnada aşağıdaki kırmızı simidin ve mavi - simidin büyüklüklerinin değiştiğini - görebilirsiniz. Daha büyük bir simit daha - çok kazanca karşılık gelir ve bu miktarın - nasıl değiştiği de kaydırıcı hareket ettikçe + Kullanılan torbanın{" "} + + Kırmızı torba + {" "} + olma ihtimalinin sizce{" "} + + 100'de kaç olduğunu{" "} + {" "} + bir kaydırıcıyı sağa ya da sola sürükleyerek + bildireceksiniz. Bunu aşağıda gördüğünüz + özel düzenek yoluyla yapacaksınız. Bu esnada + kırmızı simidin ve mavi simidin + büyüklüklerinin değiştiğini görebilirsiniz. + Daha büyük bir simit daha çok puana karşılık + gelir. Bu puan simidin tam altında yazar ve + kaydırıcı hareket ettikçe nasıl değiştiği görülebilir. Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. - Şayet o turda Kırmızı torba kullanılmış ise, - kazancınız kırmızı simidin karşılık geldiği - miktar olacak. Şayet o turda Mavi torba + Şayet o turda{" "} + + Kırmızı torba + {" "} + kullanılmış ise, kazancınız kırmızı simidin + karşılık geldiği miktar olacak. Şayet o + turda{" "} + + Mavi torba + {" "} kullanılmış ise, kazancınız mavi simidin karşılık geldiği miktar olacak. @@ -270,14 +246,41 @@ function Intro2({ marginLeft: "125px", }} > - { - setSliderValue( - Number(event.target.value) - ); - }} - /> +
+ { + setSliderValue( + Number(event.target.value) + ); + }} + /> +
+ Sizce, seçilen torbanın{" "} + + kırmızı torba + {" "} + olma ihtimali: Yüzde {sliderValue}. +
+
+ Sizce, seçilen torbanın{" "} + + mavi torba + {" "} + olma ihtimali: Yüzde {100 - sliderValue} + . +
+
) { setRedRatio(Number(e.target.value)); @@ -127,7 +127,12 @@ function Round({ return (
<> - + - {subPhase==="input" && } - {(subPhase==="input" || subPhase==="result") && } + {subPhase === "input" && ( + + )} + {(subPhase === "input" || subPhase === "result") && ( + + )} {subPhase === "result" && (
{`${calculatePointsForRound()} kazandınız.`}
)} - {(subPhase==="input" || subPhase==="result") && + {(subPhase === "input" || subPhase === "result") && ( - } + )}
); diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index 1cbbc77..2e8b96c 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -1,18 +1,13 @@ import customStyles from "@/styles/Custom.module.css"; const phaseName = new Map(); -phaseName.set("INTRO","Giriş"); -phaseName.set("INTRO2","Giriş"); -phaseName.set("MAIN","Giriş"); -phaseName.set("END","Sonuç"); +phaseName.set("INTRO", "Giriş"); +phaseName.set("INTRO2", "Giriş"); +phaseName.set("MAIN", "Giriş"); +phaseName.set("END", "Sonuç"); -function TopBar({phase}:{phase:string}) { - - return ( -
- {phaseName.get(phase)} -
- ); +function TopBar({ phase }: { phase: string }) { + return
{phaseName.get(phase)}
; } -export default TopBar; \ No newline at end of file +export default TopBar; diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index d110837..f3f99c7 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -2,7 +2,17 @@ import customStyles from "@/styles/Custom.module.css"; import circleStyles from "@/styles/Circles.module.css"; import { Text } from "@mantine/core"; -function BagHolder({ aBlue, bBlue, diceText, showBalls=true }: { aBlue: number; bBlue: number; diceText:[String,String]; showBalls?:boolean }) { +function BagHolder({ + aBlue, + bBlue, + diceText, + showBalls = true, +}: { + aBlue: number; + bBlue: number; + diceText: [String, String]; + showBalls?: boolean; +}) { return (
@@ -13,14 +23,16 @@ function BagHolder({ aBlue, bBlue, diceText, showBalls=true }: { aBlue: number; {100 - bBlue} adet{" "} kırmızı bilye - {showBalls &&
- {[...Array(bBlue)].map((e, i) => ( -
🔵
- ))} - {[...Array(100 - bBlue)].map((e, i) => ( -
🔴
- ))} -
} + {showBalls && ( +
+ {[...Array(bBlue)].map((e, i) => ( +
🔵
+ ))} + {[...Array(100 - bBlue)].map((e, i) => ( +
🔴
+ ))} +
+ )} Zar sonucu {diceText[0]} ise kullanılır.
@@ -32,14 +44,16 @@ function BagHolder({ aBlue, bBlue, diceText, showBalls=true }: { aBlue: number; kırmızı bilye - {showBalls &&
- {[...Array(aBlue)].map((e, i) => ( -
🔵
- ))} - {[...Array(100 - aBlue)].map((e, i) => ( -
🔴
- ))} -
} + {showBalls && ( +
+ {[...Array(aBlue)].map((e, i) => ( +
🔵
+ ))} + {[...Array(100 - aBlue)].map((e, i) => ( +
🔴
+ ))} +
+ )} Zar sonucu {diceText[1]} ise kullanılır.
diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index f8f56c1..070b831 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -12,7 +12,12 @@ interface drawingProps { fullView?: boolean; } -function Drawing({ numberofBlues, numberOfDraws, nextFunction,fullView=true }: drawingProps) { +function Drawing({ + numberofBlues, + numberOfDraws, + nextFunction, + fullView = true, +}: drawingProps) { const [numberOfShownBalls, setNumberOfShownBalls] = useState(-1); const interval = useInterval(() => { @@ -44,39 +49,40 @@ function Drawing({ numberofBlues, numberOfDraws, nextFunction,fullView=true }: d first_draw_blue: draws.current[0] === undefined ? null - : draws.current[0]==="blue", + : draws.current[0] === "blue", second_draw_blue: draws.current[1] === undefined ? null - : draws.current[1]==="blue", + : draws.current[1] === "blue", third_draw_blue: draws.current[2] === undefined ? null - : draws.current[2]==="blue", + : draws.current[2] === "blue", fourth_draw_blue: draws.current[3] === undefined ? null - : draws.current[3]==="blue", + : draws.current[3] === "blue", fifth_draw_blue: draws.current[4] === undefined ? null - : draws.current[4]==="blue", + : draws.current[4] === "blue", sixth_draw_blue: draws.current[5] === undefined ? null - : draws.current[5]==="blue", + : draws.current[5] === "blue", }); } return ( <> - {fullView && - <> -

Çekilen toplar:

-

- Bu turda {numberOfDraws} top çekilecek. -

- } + {fullView && ( + <> +

Çekilen toplar:

+

+ {numberOfDraws>0 ? `Bu turda ${numberOfDraws} top çekilecek.`: `Bu turda hiç top çekilmeyecek.`} +

+ + )}
))}
- {fullView && } + {fullView && ( + + )} ); } diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index df9aee6..6e36869 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -34,10 +34,15 @@ export default function Home({ .join("&"); } console.log(pass); - const respond = await fetch("../api/round" + res, { - method: "GET", - headers: { Authorization: pass }, - }); + const respond = await fetch( + process.env.NODE_ENV === "production" + ? `./api/round` + : "../api/round" + res, + { + method: "GET", + headers: { Authorization: pass }, + } + ); const columnNames = [ "id", @@ -163,7 +168,11 @@ export default function Home({ selectedRecords={selectedSessions} onSelectedRecordsChange={setSelectedSessions} onRowClick={(session) => { - router.push(`./admin/${session.id}`); + router.push( + process.env.NODE_ENV === "production" + ? `./belief/admin/${session.id}` + : `./admin/${session.id}` + ); }} /> diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 0bcb700..e3f9d9a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -15,8 +15,8 @@ export default function Home({ return ; } -export interface SessionType extends Omit { - prior: [number,number] +export interface SessionType extends Omit { + prior: [number, number]; } const defaultSession: Omit = { diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index ea50629..105e978 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -92,7 +92,7 @@ .reward { margin: 3ch; text-align: center; - margin-top:5ch; + margin-top: 5ch; } .footer { @@ -116,7 +116,7 @@ color: rgb(47, 47, 203); } -.topbar{ +.topbar { position: fixed; left: 0px; top: 0px; @@ -124,5 +124,5 @@ background-color: rgb(226, 241, 247); box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px; margin-top: 0px; - padding:1ch 5ch; -} \ No newline at end of file + padding: 1ch 5ch; +} diff --git a/src/styles/globals.css b/src/styles/globals.css index 7e0c4d3..14acbc0 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -70,4 +70,4 @@ body { a { color: inherit; text-decoration: none; -} \ No newline at end of file +} diff --git a/src/utilities/functions.ts b/src/utilities/functions.ts index c6c80c7..3a78552 100644 --- a/src/utilities/functions.ts +++ b/src/utilities/functions.ts @@ -37,11 +37,14 @@ export function downloadDataAsCsv( ); } -export function getDiceText(prior: [number, number]):[String,String] { - const formatter = new Intl.ListFormat('tr', { style: 'long', type: 'disjunction' }); - const allDice = ["1", "2", "3", "4", "5", "6"]; - return [ - formatter.format(allDice.slice(0, prior[0])), - formatter.format(allDice.slice(prior[1])), - ]; +export function getDiceText(prior: [number, number]): [String, String] { + const formatter = new Intl.ListFormat("tr", { + style: "long", + type: "disjunction", + }); + const allDice = ["1", "2", "3", "4", "5", "6"]; + return [ + formatter.format(allDice.slice(0, prior[0])), + formatter.format(allDice.slice(prior[1])), + ]; } From e3650b6e5b6dd9944ac933fbc9c8c2901e702a64 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 27 May 2023 15:01:18 +0300 Subject: [PATCH 15/24] bsr introduction update --- src/components/Intro2.tsx | 86 +++++++++++++++---- .../experimentComponents/Drawing.tsx | 4 +- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index 8dc166c..5c170ad 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -200,7 +200,10 @@ function Intro2({ {treatment === "QSR" ? (
- + Kullanılan torbanın{" "} @@ -291,21 +294,45 @@ function Intro2({
) : (
- + - Burada kaydırıcıyı sağa ya da sola - sürükleyerek size göre Kırmızı torbanın - kullanılmış olma ihtimalini bildireceksiniz. - Bu esnada aşağıdaki kırmızı simidin ve mavi - simidin büyüklüklerinin değiştiğini - görebilirsiniz. + Kullanılan torbanın{" "} + + Kırmızı torba + {" "} + olma ihtimalinin sizce{" "} + + 100'de kaç olduğunu{" "} + {" "} + bir kaydırıcıyı sağa ya da sola sürükleyerek + bildireceksiniz. Bunu aşağıda gördüğünüz + özel düzenek yoluyla yapacaksınız. Bu esnada + kırmızı simidin ve mavi simidin + büyüklüklerinin değiştiğini görebilirsiniz. + Karar verdikten sonra, gerçekte hangi + torbanın kullanıldığı size bildirilecektir. Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Ardından, seçilen torbanın rengindeki simit ve içindeki alanın teşkil ettiği daireden rastgele bir nokta seçilecek. + {/* Şayet o turda{" "} + + Kırmızı torba + {" "} + kullanılmış ise, kazancınız kırmızı simidin + karşılık geldiği miktar olacak. Şayet o + turda{" "} + + Mavi torba + {" "} + kullanılmış ise, kazancınız mavi simidin + karşılık geldiği miktar olacak. */} Eğer bu nokta ilgili simite, yani tam @@ -323,14 +350,41 @@ function Intro2({ marginLeft: "125px", }} > - { - setSliderValue( - Number(event.target.value) - ); - }} - /> +
+ { + setSliderValue( + Number(event.target.value) + ); + }} + /> +
+ Sizce, seçilen torbanın{" "} + + kırmızı torba + {" "} + olma ihtimali: Yüzde {sliderValue}. +
+
+ Sizce, seçilen torbanın{" "} + + mavi torba + {" "} + olma ihtimali: Yüzde {100 - sliderValue} + . +
+

Çekilen toplar:

- {numberOfDraws>0 ? `Bu turda ${numberOfDraws} top çekilecek.`: `Bu turda hiç top çekilmeyecek.`} + {numberOfDraws > 0 + ? `Bu turda ${numberOfDraws} top çekilecek.` + : `Bu turda hiç top çekilmeyecek.`}

)} From c4580c6456956bef8ce72a72d37d3342ded46a25 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sun, 28 May 2023 11:47:18 +0300 Subject: [PATCH 16/24] getting ready for demographics and gps --- .../migration.sql | 3 + .../migration.sql | 9 + prisma/schema.prisma | 2 + src/components/Demographics.tsx | 208 ++++++++++++++++++ src/components/Experiment.tsx | 18 +- src/components/Intro2.tsx | 118 +++++----- src/components/Round.tsx | 4 +- src/components/TopBar.tsx | 1 + .../experimentComponents/BagHolder.tsx | 28 +-- .../experimentComponents/Circles.tsx | 38 ++-- .../experimentComponents/Slider.tsx | 63 ++++-- src/styles/Circles.module.css | 2 + src/styles/Custom.module.css | 4 +- src/styles/Demographics.module.css | 45 ++++ src/styles/globals.css | 27 +++ src/utilities/types.ts | 1 + 16 files changed, 450 insertions(+), 121 deletions(-) create mode 100644 prisma/migrations/20230527170338_added_charity_pre_exp/migration.sql create mode 100644 prisma/migrations/20230527170430_small_casing_correction/migration.sql create mode 100644 src/components/Demographics.tsx create mode 100644 src/styles/Demographics.module.css diff --git a/prisma/migrations/20230527170338_added_charity_pre_exp/migration.sql b/prisma/migrations/20230527170338_added_charity_pre_exp/migration.sql new file mode 100644 index 0000000..5499da3 --- /dev/null +++ b/prisma/migrations/20230527170338_added_charity_pre_exp/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "Participant" ADD COLUMN "gps_charity" INTEGER, +ADD COLUMN "preExp" INTEGER; diff --git a/prisma/migrations/20230527170430_small_casing_correction/migration.sql b/prisma/migrations/20230527170430_small_casing_correction/migration.sql new file mode 100644 index 0000000..be1f790 --- /dev/null +++ b/prisma/migrations/20230527170430_small_casing_correction/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - You are about to drop the column `preExp` on the `Participant` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Participant" DROP COLUMN "preExp", +ADD COLUMN "pre_exp" INTEGER; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e79f8a8..65da230 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -15,6 +15,7 @@ model Participant { Round Round[] age Int? gpa Float? + pre_exp Int? sex Int? dep String? num_of_econ Int? @@ -24,6 +25,7 @@ model Participant { gps_future_benefit Int? gps_punish_self Int? gps_punish_other Int? + gps_charity Int? gps_d1 Int? gps_d2 Int? gps_d3 Int? diff --git a/src/components/Demographics.tsx b/src/components/Demographics.tsx new file mode 100644 index 0000000..cfc0e1f --- /dev/null +++ b/src/components/Demographics.tsx @@ -0,0 +1,208 @@ +import { + Select, + NumberInput, + Radio, + Group, + TextInput, + Grid, + Flex, + Button, + Divider, + Box, +} from "@mantine/core"; +import { useForm, isNotEmpty } from "@mantine/form"; + +interface DemographicData { + age: number; + gpa: number; + pre_exp: number; + sex: number; + dep: string; + num_of_econ: number; + diff: number; + sure: number; +} + +function Demographics({ participantId }: { participantId: string }) { + async function sendData(data: DemographicData) { + console.log(data); + await fetch(`./api/participant/${participantId}`, { + method: "PUT", + body: JSON.stringify(data), + }); + } + + const form = useForm({ + initialValues: { + age: null, + gpa: null, + pre_exp: null, + sex: null, + dep: "", + num_of_econ: null, + diff: null, + sure: null, + }, + + validate: { + age: isNotEmpty("Lütfen yaşınızı girin."), + gpa: isNotEmpty("Lütfen ortalamanızı girin."), + pre_exp: isNotEmpty("Lütfen tecrübenizi girin."), + sex: isNotEmpty("Lütfen cinsiyetinizi girin."), + dep: isNotEmpty("Lütfen bölümünüzü girin."), + num_of_econ: isNotEmpty("Lütfen ders sayısını girin."), + diff: isNotEmpty("Lütfen zorlanma miktarınızı girin."), + sure: isNotEmpty("Lütfen kendinizden emin olma durumunuzu girin."), + }, + }); + + return ( + sendData(data))}> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default Demographics; diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index 9f2c7fc..91f2964 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -8,9 +8,10 @@ import TopBar from "@/components/TopBar"; import Footer from "./Footer"; import { Participant } from "@prisma/client"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import Round from "@/components/Round"; +import Demographics from "@/components/Demographics"; import { Phase } from "@/utilities/types"; @@ -37,9 +38,15 @@ function Experiment({ data }: { data: SessionType }) { setPhase(Phase.Intro2); } + useEffect(() => { + console.log(data); + shuffle(data.drawn_balls); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const [phase, setPhase] = useState("INTRO"); // const [phase, setPhase] = useState("MAIN"); - const randomizedDraws = useRef(shuffle(data.drawn_balls)); + const randomizedDraws = useRef(data.drawn_balls); const [points, setPoints] = useState(0); return ( @@ -71,6 +78,13 @@ function Experiment({ data }: { data: SessionType }) { } /> )} + {phase === "DEMO" && ( + + )} {phase === "END" && (
Deney Bitti. Kazandığınız toplam puan: {points}
)} diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index 5c170ad..6204d96 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -197,31 +197,64 @@ function Intro2({
+ + + + + Kullanılan torbanın{" "} + kırmızı veya{" "} + mavi olma + ihtimalinin{" "} + + 100'de kaç olduğunu + {" "} + ekrandaki bir kaydırıcıyı sağa ya da sola + sürükleyerek bildireceksiniz. Aşağıda bu kaydırıcıyı + görebilirsiniz. + + + Şimdi dilerseniz bunu sağa ya da sola sürüklemeyi + deneyin. Soldaki ve sağdaki rakamların değiştiğini + göreceksiniz. Solda kırmızı renkle yazılan rakam, + sizce kullanılan torbanın{" "} + + Kırmızı torba + {" "} + olma ihtimalinin 100’de kaç olduğunu gösterir. Sağda + mavi renkle yazılan rakam sizce kullanılan torbanın{" "} + Mavi olma + ihtimalinin 100'de kaç olduğunu gösterir. + +
+ { + setSliderValue(Number(event.target.value)); + }} + /> +
+
+
{treatment === "QSR" ? ( -
+
- Kullanılan torbanın{" "} - - Kırmızı torba - {" "} - olma ihtimalinin sizce{" "} - - 100'de kaç olduğunu{" "} - {" "} - bir kaydırıcıyı sağa ya da sola sürükleyerek - bildireceksiniz. Bunu aşağıda gördüğünüz - özel düzenek yoluyla yapacaksınız. Bu esnada - kırmızı simidin ve mavi simidin + Karar ekranında, bahsettiğimiz kaydırıcının + tam altında kırmızı ve mavi birer simit + olacak. Kaydırıcıyı sağa yahut sola + sürükledikçe kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini görebilirsiniz. Daha büyük bir simit daha çok puana karşılık - gelir. Bu puan simidin tam altında yazar ve - kaydırıcı hareket ettikçe nasıl değiştiği - görülebilir. + gelir. Bu puan simidin tam altında yazar. Karar verdikten sonra, gerçekte hangi @@ -243,10 +276,10 @@ function Intro2({
@@ -258,31 +291,6 @@ function Intro2({ ); }} /> -
- Sizce, seçilen torbanın{" "} - - kırmızı torba - {" "} - olma ihtimali: Yüzde {sliderValue}. -
-
- Sizce, seçilen torbanın{" "} - - mavi torba - {" "} - olma ihtimali: Yüzde {100 - sliderValue} - . -
- Karar verdikten sonra, gerçekte hangi - torbanın kullanıldığı size bildirilecektir. Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size bildirilecektir. Ardından, seçilen torbanın rengindeki simit ve içindeki alanın teşkil ettiği daireden rastgele bir nokta seçilecek. - {/* Şayet o turda{" "} - - Kırmızı torba - {" "} - kullanılmış ise, kazancınız kırmızı simidin - karşılık geldiği miktar olacak. Şayet o - turda{" "} - - Mavi torba - {" "} - kullanılmış ise, kazancınız mavi simidin - karşılık geldiği miktar olacak. */} Eğer bu nokta ilgili simite, yani tam @@ -417,6 +411,10 @@ function Intro2({ {showNextPhase && ( )} diff --git a/src/components/Round.tsx b/src/components/Round.tsx index 86480be..cf88f94 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -36,7 +36,7 @@ function Round({ participantId: string; }) { const [redRatio, setRedRatio] = useState(50); - const [currentRound, setCurrentRound] = useState(1); + const [currentRound, setCurrentRound] = useState(0); const [selectedBag, setSelectedBag] = useState<"blue" | "red">( Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" : "red" ); @@ -97,7 +97,7 @@ function Round({ participantId: participantId, chosen_probability: 100 - redRatio, reward: calculatePointsForRound(), - round: currentRound, + round: currentRound + 1, }; console.log(lastRound); generateNewRound(lastRound); diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index 2e8b96c..263dc8b 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -5,6 +5,7 @@ phaseName.set("INTRO", "Giriş"); phaseName.set("INTRO2", "Giriş"); phaseName.set("MAIN", "Giriş"); phaseName.set("END", "Sonuç"); +phaseName.set("DEMO", "Anket"); function TopBar({ phase }: { phase: string }) { return
{phaseName.get(phase)}
; diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index f3f99c7..e34a0ef 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -17,45 +17,45 @@ function BagHolder({
- Mavi Torba:{" "} - {bBlue} adet{" "} + Kırmızı Torba:{" "} + {aBlue} adet{" "} mavi bilye,{" "} - {100 - bBlue} adet{" "} + {100 - aBlue} adet{" "} kırmızı bilye + {showBalls && (
- {[...Array(bBlue)].map((e, i) => ( + {[...Array(aBlue)].map((e, i) => (
🔵
))} - {[...Array(100 - bBlue)].map((e, i) => ( + {[...Array(100 - aBlue)].map((e, i) => (
🔴
))}
)} - Zar sonucu {diceText[0]} ise kullanılır. + + Zar sonucu {diceText[1]} ise kullanılır.
- Kırmızı Torba:{" "} - {aBlue} adet{" "} + Mavi Torba:{" "} + {bBlue} adet{" "} mavi bilye,{" "} - {100 - aBlue} adet{" "} + {100 - bBlue} adet{" "} kırmızı bilye - {showBalls && (
- {[...Array(aBlue)].map((e, i) => ( + {[...Array(bBlue)].map((e, i) => (
🔵
))} - {[...Array(100 - aBlue)].map((e, i) => ( + {[...Array(100 - bBlue)].map((e, i) => (
🔴
))}
)} - - Zar sonucu {diceText[1]} ise kullanılır. + Zar sonucu {diceText[0]} ise kullanılır.
); diff --git a/src/components/experimentComponents/Circles.tsx b/src/components/experimentComponents/Circles.tsx index 7551f30..9c22cc0 100644 --- a/src/components/experimentComponents/Circles.tsx +++ b/src/components/experimentComponents/Circles.tsx @@ -63,17 +63,18 @@ function Circles({ return (
- {showBlue && ( + {showRed && (
-

{(100 - value) ** 2}

+

{value ** 2}

)} - {showRed && ( + {showBlue && (
-

{value ** 2}

+

{(100 - value) ** 2}

)}
diff --git a/src/components/experimentComponents/Slider.tsx b/src/components/experimentComponents/Slider.tsx index 346cf73..7f50869 100644 --- a/src/components/experimentComponents/Slider.tsx +++ b/src/components/experimentComponents/Slider.tsx @@ -8,31 +8,50 @@ interface sliderProps { function Slider({ updatingFunction, value, disabled }: sliderProps) { return ( -
-
- updatingFunction(e)} - disabled={disabled} - /> -
+
+
+ {value} +
+
+
+ updatingFunction(e)} + disabled={disabled} + /> +
+
+
-
+
+ +
+ {100 - value}
); diff --git a/src/styles/Circles.module.css b/src/styles/Circles.module.css index df7db88..7ef7504 100644 --- a/src/styles/Circles.module.css +++ b/src/styles/Circles.module.css @@ -16,6 +16,7 @@ text-align: center; position: relative; min-height: 100px; + width: 300px; } .wrap { @@ -102,6 +103,7 @@ gap: 50px; max-width: 100%; flex-wrap: wrap; + justify-content: center; } .bar-holder { diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index 105e978..02ddb9e 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -71,12 +71,12 @@ margin-bottom: 2ch; } -.bagHolder > :nth-child(1) { +.bagHolder > :nth-child(2) { border: 5px #55acee solid; border-radius: 3ch; } -.bagHolder > :nth-child(2) { +.bagHolder > :nth-child(1) { border: 5px #dd2e44 solid; border-radius: 3ch; } diff --git a/src/styles/Demographics.module.css b/src/styles/Demographics.module.css new file mode 100644 index 0000000..14461a9 --- /dev/null +++ b/src/styles/Demographics.module.css @@ -0,0 +1,45 @@ +.label { + display: block; + font-size: 14px; + font-weight: bold; + padding: 18px 0 0 0; + margin-bottom: 10px; +} +.likert { + list-style: none; + width: 100%; + margin: 0; + padding: 0 0 35px; + display: block; + border-bottom: 2px solid #efefef; +} +.likert:last-of-type { + border-bottom: 0; +} +.likert:before { + content: ""; + position: relative; + top: 11px; + left: 5%; + display: block; + background-color: #efefef; + height: 4px; + width: 80%; +} +.likert li { + display: inline-block; + width: 8%; + text-align: center; + vertical-align: top; +} +.likert li input[type="radio"] { + display: block; + position: relative; + top: 0; + left: 50%; + margin-left: -6px; +} + +div .likert li label { + width: 100%; +} diff --git a/src/styles/globals.css b/src/styles/globals.css index 14acbc0..20e6cba 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -71,3 +71,30 @@ a { color: inherit; text-decoration: none; } + +.mantine-RadioGroup-root.likert .mantine-Radio-body { + flex-direction: column; + /* max-width: 30px; */ + justify-content: center; +} + +.mantine-RadioGroup-root.likert .mantine-Radio-root { + margin-top: 5px; + align-self: flex-start; + width: 35px; +} + +.mantine-Radio-inner { + margin-inline: auto; +} + +.likert:before { + content: ""; + position: relative; + top: 45px; + left: 10px; + display: block; + background-color: #efefef; + height: 4px; + width: 495px; +} diff --git a/src/utilities/types.ts b/src/utilities/types.ts index c3cce4c..022f72c 100644 --- a/src/utilities/types.ts +++ b/src/utilities/types.ts @@ -2,6 +2,7 @@ export const enum Phase { Intro = "INTRO", Intro2 = "INTRO2", Main = "MAIN", + Demographics = "DEMO", End = "END", } From 642d8c1db8a087bb792eec44872618304281b67a Mon Sep 17 00:00:00 2001 From: emrergin Date: Sun, 28 May 2023 11:51:19 +0300 Subject: [PATCH 17/24] adds points to topbar --- src/components/Demographics.tsx | 9 ++++++--- src/components/Experiment.tsx | 4 ++-- src/components/Intro2.tsx | 2 +- src/components/TopBar.tsx | 9 +++++++-- src/styles/Custom.module.css | 2 ++ 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/components/Demographics.tsx b/src/components/Demographics.tsx index cfc0e1f..d85278f 100644 --- a/src/components/Demographics.tsx +++ b/src/components/Demographics.tsx @@ -57,7 +57,10 @@ function Demographics({ participantId }: { participantId: string }) { }); return ( - sendData(data))}> + sendData(data))} + > @@ -110,7 +118,7 @@ function Demographics({ participantId }: { participantId: string }) { @@ -118,7 +126,7 @@ function Demographics({ participantId }: { participantId: string }) { label="Bugüne kadar kaç ekonomi dersi aldınız?" style={{ maxWidth: "200px" }} placeholder="Seçiniz" - required + withAsterisk {...form.getInputProps("num_of_econ")} data={[ { value: "0", label: "0" }, @@ -137,7 +145,7 @@ function Demographics({ participantId }: { participantId: string }) { düşündünüz?" {...form.getInputProps("diff")} className="likert" - required + withAsterisk > @@ -159,7 +167,7 @@ function Demographics({ participantId }: { participantId: string }) { label="Deneydeki seçimleriniz hakkında ne kadar emindiniz?" {...form.getInputProps("sure")} className="likert" - required + withAsterisk > diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5ece6e8..7fc543d 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -13,7 +13,7 @@ export default function App(props: AppProps) { Ekonomi Deneyi +) { + if (req.method === "PUT") { + const { body } = req; + const { id } = req.query; + try { + if (typeof id === "string") { + const updateUser = await prisma.participant.update({ + where: { + id, + }, + data: JSON.parse(body), + }); + return res.status(200).json(updateUser); + } + + return res.status(422); + } catch (e) { + console.log(e); + return res.status(422); + } + } + res.end(); +} From c5d5e0467440e4ad93fa7956310af633e060e396 Mon Sep 17 00:00:00 2001 From: emrergin Date: Sat, 3 Jun 2023 01:17:06 +0300 Subject: [PATCH 19/24] demographics added, gps start --- README.md | 4 +- src/components/Demographics.tsx | 10 +- src/components/Experiment.tsx | 19 +- src/components/Gps.tsx | 47 +++++ src/components/Intro.tsx | 8 +- src/components/Intro2.tsx | 6 +- src/components/Round.tsx | 4 +- src/components/gpsComponents/Describe.tsx | 144 ++++++++++++++ src/components/gpsComponents/GeneralRisk.tsx | 49 +++++ src/components/gpsComponents/Gift.tsx | 20 ++ src/components/gpsComponents/HypoDonation.tsx | 20 ++ .../gpsComponents/StairPatience.tsx | 38 ++++ src/components/gpsComponents/StairRisk.tsx | 63 ++++++ .../gpsComponents/WillingnessToAct.tsx | 130 ++++++++++++ src/pages/admin/index.tsx | 188 ++++++++++++++++-- src/pages/api/admin.ts | 21 ++ src/pages/index.tsx | 7 +- src/styles/Custom.module.css | 1 + src/styles/globals.css | 60 +++++- src/utilities/functions.ts | 16 ++ src/utilities/types.ts | 1 + 21 files changed, 814 insertions(+), 42 deletions(-) create mode 100644 src/components/Gps.tsx create mode 100644 src/components/gpsComponents/Describe.tsx create mode 100644 src/components/gpsComponents/GeneralRisk.tsx create mode 100644 src/components/gpsComponents/Gift.tsx create mode 100644 src/components/gpsComponents/HypoDonation.tsx create mode 100644 src/components/gpsComponents/StairPatience.tsx create mode 100644 src/components/gpsComponents/StairRisk.tsx create mode 100644 src/components/gpsComponents/WillingnessToAct.tsx create mode 100644 src/pages/api/admin.ts diff --git a/README.md b/README.md index deade1b..06211c6 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Joint project with [Mehmet Yiğit Gürdal](https://econ.boun.edu.tr/mehmet-yigit - **Prisma** as the ORM for migrations and database access. - **PostgreSQL** as the database. - **TypeScript** as the programming language. +- **Mantine** as the UI library. ## Details @@ -30,4 +31,5 @@ Some introductory readings for the concepts. - This is the first Next.js app I completed. - This is the first time I am using Prisma, and also PostgreSQL. - For autoanimate to work as expected, the parent element needs to have a specified width. -- My first use case of ``Intl.ListFormat``. \ No newline at end of file +- My first use case of ``Intl.ListFormat``. +- I learned that `new Date()` is not safe to use with Next.js outside of a useEffect call. \ No newline at end of file diff --git a/src/components/Demographics.tsx b/src/components/Demographics.tsx index 1a17217..f941357 100644 --- a/src/components/Demographics.tsx +++ b/src/components/Demographics.tsx @@ -22,8 +22,15 @@ interface DemographicData { diff: number | null; sure: number | null; } +import { Phase } from "@/utilities/types"; -function Demographics({ participantId }: { participantId: string }) { +function Demographics({ + participantId, + phaseFunction, +}: { + participantId: string; + phaseFunction: (p: Phase) => void; +}) { async function sendData(data: DemographicData) { const castedData = { ...data, @@ -38,6 +45,7 @@ function Demographics({ participantId }: { participantId: string }) { method: "PUT", body: JSON.stringify(castedData), }); + phaseFunction(Phase.End); } const form = useForm({ diff --git a/src/components/Experiment.tsx b/src/components/Experiment.tsx index a4abedf..5a39dca 100644 --- a/src/components/Experiment.tsx +++ b/src/components/Experiment.tsx @@ -1,5 +1,5 @@ import styles from "@/styles/Home.module.css"; -import cStyles from "@/styles/Custom.module.css"; +// import cStyles from "@/styles/Custom.module.css"; import Intro from "@/components/Intro"; import Intro2 from "@/components/Intro2"; @@ -12,6 +12,7 @@ import { useEffect, useRef, useState } from "react"; import Round from "@/components/Round"; import Demographics from "@/components/Demographics"; +import Gps from "@/components/Gps"; import { Phase } from "@/utilities/types"; @@ -36,6 +37,7 @@ function Experiment({ data }: { data: SessionType }) { }); setParticipant(await respond.json()); setPhase(Phase.Intro2); + // setPhase(Phase.Gps) } useEffect(() => { @@ -44,7 +46,7 @@ function Experiment({ data }: { data: SessionType }) { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const [phase, setPhase] = useState("INTRO"); + const [phase, setPhase] = useState("GPS"); // const [phase, setPhase] = useState("MAIN"); const randomizedDraws = useRef(data.drawn_balls); const [points, setPoints] = useState(0); @@ -62,6 +64,7 @@ function Experiment({ data }: { data: SessionType }) { priors={data.prior as [number, number]} treatment={data.treatment} phaseFunction={setPhase} + numberOfRounds={data.drawn_balls.length} /> )} {phase === "MAIN" && ( @@ -83,12 +86,20 @@ function Experiment({ data }: { data: SessionType }) { participantId={ "id" in participant ? participant.id : "no-id-given" } + phaseFunction={setPhase} /> )} + {phase === "GPS" && } {phase === "END" && ( -
Deney Bitti. Kazandığınız toplam puan: {points}
+
+
Deney Bitti. Kazandığınız toplam puan: {points}
+
+ Kazandığınız toplam para:{" "} + {20 + Math.round(points / 1000)} TL +
+
)} -
+ {phase !== "MAIN" &&
}
); } diff --git a/src/components/Gps.tsx b/src/components/Gps.tsx new file mode 100644 index 0000000..74c2335 --- /dev/null +++ b/src/components/Gps.tsx @@ -0,0 +1,47 @@ +import { Phase } from "@/utilities/types"; +import { useState } from "react"; + +import GeneralRisk from "@/components/gpsComponents/GeneralRisk"; +import WillingnessToAct from "@/components/gpsComponents/WillingnessToAct"; +import Describe from "@/components/gpsComponents/Describe"; +import StairRisk from "@/components/gpsComponents/StairRisk"; +import Gift from "@/components/gpsComponents/Gift"; +import HypoDonation from "@/components/gpsComponents/HypoDonation"; +import StairPatience from "@/components/gpsComponents/StairPatience"; + +const questionList = [ + `generalrisk`, + `willingnesstoact`, + `describe`, + `stairrisk`, + `gift`, + `hypodonation`, + `stairpatience`, +]; + +function Gps({ phaseFunction }: { phaseFunction: (p: Phase) => void }) { + const [question, setQuestion] = useState("generalrisk"); + return ( +
+ {question === "generalrisk" && ( + + )} + {question === "willingnesstoact" && ( + + )} + {question === "describe" && } + {question === "stairrisk" && ( + + )} + {question === "gift" && } + {question === "hypodonation" && ( + + )} + {question === "stairpatience" && ( + + )} +
+ ); +} + +export default Gps; diff --git a/src/components/Intro.tsx b/src/components/Intro.tsx index acb877d..ce26930 100644 --- a/src/components/Intro.tsx +++ b/src/components/Intro.tsx @@ -30,8 +30,8 @@ function Intro({ Oyunlarda kazancınızı "puan" cinsinden hesaplayacağız. Toplam puanınızın parasal değerini ve ek - olarak bir katılım ücretini size deney sonunda nakit olarak - ödeyeceğiz. + olarak 20 TL katılım ücretini size deney sonunda nakit + olarak ödeyeceğiz. 1000 puan = 1 TL olarak hesaplanır. Oyunları tamamladıktan sonra size dair bazı demografik @@ -40,8 +40,8 @@ function Intro({ Deneyden erken ayrılabilirsiniz. Bulunduğunuz sayfayı değiştirmeniz ve yenilemeniz gibi durumlarda da deneyden - erken ayrılmış sayılacaksınız. Erken ayrılmanız durumunda o - zamana kadarki kararlarınız değerlendirilecek. + erken ayrılmış sayılacaksınız. Erken ayrılmanız durumunda + yalnızca katılım ücreti ödenir.
diff --git a/src/components/Intro2.tsx b/src/components/Intro2.tsx index a9d3189..e0df0e6 100644 --- a/src/components/Intro2.tsx +++ b/src/components/Intro2.tsx @@ -20,12 +20,14 @@ function Intro2({ bBlue, priors, treatment, + numberOfRounds, phaseFunction, }: { aBlue: number; bBlue: number; priors: [number, number]; treatment: string; + numberOfRounds: number; phaseFunction: (p: Phase) => void; }) { const [sliderValue, setSliderValue] = useState(50); @@ -77,8 +79,8 @@ function Intro2({ - Turlar: Deneyimiz otuz "tur"dan - oluşuyor. + Turlar: Deneyimiz {numberOfRounds}{" "} + "tur"dan oluşuyor. Hangi Torbanın Kullanıldığını Tahmin Etme:{" "} diff --git a/src/components/Round.tsx b/src/components/Round.tsx index cf88f94..a17bf33 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -104,7 +104,7 @@ function Round({ setPoint(calculatePointsForRound() + point); pointFunction(calculatePointsForRound() + point); - if (currentRound < numberOfRounds) { + if (currentRound < numberOfRounds - 1) { const newBag = Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" @@ -119,7 +119,7 @@ function Round({ setRedRatio(50); time.current = new Date(); } else { - phaseFunction(Phase.End); + phaseFunction(Phase.Demographics); pointFunction(point); } } diff --git a/src/components/gpsComponents/Describe.tsx b/src/components/gpsComponents/Describe.tsx new file mode 100644 index 0000000..d4c0a01 --- /dev/null +++ b/src/components/gpsComponents/Describe.tsx @@ -0,0 +1,144 @@ +import { Button, Container, Radio, Divider } from "@mantine/core"; + +function Describe({ setSubphase }: { setSubphase: (p: string) => void }) { + return ( + +

Aşağıdaki ifadelerden her biri sizi ne kadar iyi tanımlar?

+

+ Lütfen cevabınızı 0'dan 10'a kadar bir ölçekte belirtin. + 0 “beni hiç ifade etmiyor” ve 10 “beni mükemmel şekilde ifade + ediyor” anlamına gelir. Ölçekte nereye düştüğünüzü belirtmek + için 0 ile 10 arasında herhangi bir sayı kullanabilirsiniz. +

+ + + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ +
+ ); +} + +export default Describe; diff --git a/src/components/gpsComponents/GeneralRisk.tsx b/src/components/gpsComponents/GeneralRisk.tsx new file mode 100644 index 0000000..fa72954 --- /dev/null +++ b/src/components/gpsComponents/GeneralRisk.tsx @@ -0,0 +1,49 @@ +import { Radio, Button, Divider, Container } from "@mantine/core"; + +function GeneralRisk({ setSubphase }: { setSubphase: (p: string) => void }) { + return ( + +

+ Genel olarak, risk almaya istekli bir kişi mi yoksa risk + almaktan sakınan biri misiniz? +

+ + +
+ + + + + + + + + + + +
+
+ +
+ ); +} + +export default GeneralRisk; diff --git a/src/components/gpsComponents/Gift.tsx b/src/components/gpsComponents/Gift.tsx new file mode 100644 index 0000000..772cadf --- /dev/null +++ b/src/components/gpsComponents/Gift.tsx @@ -0,0 +1,20 @@ +import { Button } from "@mantine/core"; + +function Gift({ setSubphase }: { setSubphase: (p: string) => void }) { + return ( +
+

gif

+ +
+ ); +} + +export default Gift; diff --git a/src/components/gpsComponents/HypoDonation.tsx b/src/components/gpsComponents/HypoDonation.tsx new file mode 100644 index 0000000..54515f7 --- /dev/null +++ b/src/components/gpsComponents/HypoDonation.tsx @@ -0,0 +1,20 @@ +import { Button } from "@mantine/core"; + +function HypoDonation({ setSubphase }: { setSubphase: (p: string) => void }) { + return ( +
+

hypo

+ +
+ ); +} + +export default HypoDonation; diff --git a/src/components/gpsComponents/StairPatience.tsx b/src/components/gpsComponents/StairPatience.tsx new file mode 100644 index 0000000..c0d8e88 --- /dev/null +++ b/src/components/gpsComponents/StairPatience.tsx @@ -0,0 +1,38 @@ +import { Phase } from "@/utilities/types"; +import { Button } from "@mantine/core"; + +const stairPatienceMap = new Map(); +stairPatienceMap.set(62, [50, 74]); +stairPatienceMap.set(50, [45, 56]); +stairPatienceMap.set(74, [68, 81]); +stairPatienceMap.set(45, [42, 48]); +stairPatienceMap.set(56, [53, 59]); +stairPatienceMap.set(68, [65, 71]); +stairPatienceMap.set(81, [77, 84]); +stairPatienceMap.set(42, [41, 44]); +stairPatienceMap.set(48, [46, 49]); +stairPatienceMap.set(53, [52, 54]); +stairPatienceMap.set(59, [57, 60]); +stairPatienceMap.set(65, [63, 66]); +stairPatienceMap.set(71, [69, 72]); +stairPatienceMap.set(77, [76, 79]); +stairPatienceMap.set(84, [82, 86]); + +function StairPatience({ setSubphase }: { setSubphase: (p: Phase) => void }) { + return ( +
+

stairpatience

+ +
+ ); +} + +export default StairPatience; diff --git a/src/components/gpsComponents/StairRisk.tsx b/src/components/gpsComponents/StairRisk.tsx new file mode 100644 index 0000000..934d524 --- /dev/null +++ b/src/components/gpsComponents/StairRisk.tsx @@ -0,0 +1,63 @@ +import { Button, Container, Radio, Group } from "@mantine/core"; + +const inflationMultiplier = 10; +const stair1SureOutcome = 200; +const currentSure = 5; + +function StairRisk({ setSubphase }: { setSubphase: (p: string) => void }) { + return ( + +
+

Lütfen aşağıdaki durumu hayal edin:

+

+ {150 * inflationMultiplier} TL kazanma ve hiçbir şey + kazanamama arasında eşit şansa sahip olacağınız bir çekiliş + yahut belirli bir miktar kesin ödeme arasında seçim + yapabilirsiniz. Size böyle beş farklı durum sunacağız. +

+
+
+

Hangisini tercih ederdiniz:

+

+ %50 şansla{" "} + + {inflationMultiplier * stair1SureOutcome} TL + {" "} + para kazandıran ve %50 şansla hiçbir şey kazandırmayan bir + çekilişi mi yahut{" "} + {currentSure * inflationMultiplier} TL’lik + kesin bir nakit para ödemesini mi?{" "} +

+ {/* + + + */} + + + + + + + +
+ +
+ ); +} + +export default StairRisk; diff --git a/src/components/gpsComponents/WillingnessToAct.tsx b/src/components/gpsComponents/WillingnessToAct.tsx new file mode 100644 index 0000000..31434b3 --- /dev/null +++ b/src/components/gpsComponents/WillingnessToAct.tsx @@ -0,0 +1,130 @@ +import { Button, Container, Radio, Divider } from "@mantine/core"; + +function WillingnessToAct({ + setSubphase, +}: { + setSubphase: (p: string) => void; +}) { + return ( + +

+ {" "} + Şimdi size belirli bir şekilde hareket etmeye istekli olup + olmadığınızı soruyoruz. +

+

+ Lütfen cevabınızı 0'dan 10'a kadar bir ölçekte tekrar + belirtin. 0, “hiçbir şekilde yapmak istemiyor” ve 10, “yapmaya + çok istekli” anlamına gelir. Ölçekte nereye düştüğünüzü + belirtmek için 0 ile 10 arasında herhangi bir sayı + kullanabilirsiniz. +

+ + + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + +
+
+ +
+ ); +} + +export default WillingnessToAct; diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 752013b..04a14de 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -5,10 +5,21 @@ import { Session } from "@prisma/client"; import { useState, useEffect, useRef } from "react"; -import { Container, Button, Center, Modal, TextInput } from "@mantine/core"; +import { + Container, + Button, + Center, + Modal, + TextInput, + NumberInput, + Radio, + Group, + Box, +} from "@mantine/core"; +import { useForm, isNotEmpty } from "@mantine/form"; import { DataTable } from "mantine-datatable"; import { useRouter } from "next/router"; -import { downloadDataAsCsv } from "@/utilities/functions"; +import { downloadDataAsCsv, getDateText } from "@/utilities/functions"; import { useDisclosure, useLocalStorage } from "@mantine/hooks"; @@ -21,6 +32,8 @@ export default function Home({ const [pass, setPass] = useLocalStorage({ key: "pass", defaultValue: "" }); const [opened, { open, close }] = useDisclosure(false); + const [newSession, { open: sessionOpen, close: sessionClose }] = + useDisclosure(false); async function downloadData( listOfSessions: string[] = selectedSessions.map((a) => a.id) @@ -104,6 +117,89 @@ export default function Home({ } }, [open, close, pass]); + function isInDesiredForm(str: string) { + var n = Math.floor(Number(str)); + return n !== Infinity && String(n) === str && n >= 0; + } + + const form = useForm({ + initialValues: { + name: "", + num_of_blue_a: 30, + num_of_blue_b: 70, + treatment: null, + drawn_balls: "", + prior: "3,3", + }, + validate: { + name: isNotEmpty("Lütfen bir oturum ismi girin."), + num_of_blue_a: isNotEmpty("Lütfen mavi bilyelerin sayısını girin."), + num_of_blue_b: isNotEmpty("Lütfen mavi bilyelerin sayısını girin."), + treatment: isNotEmpty("Lütfen bir deney tipi girin."), + drawn_balls: (value) => { + let array = value.split(",").map((a) => a.trim()); + for (let line of array) { + if (!isInDesiredForm(line)) { + return "Negatif olmayan tam sayılar girmeniz bekleniyor."; + } + } + return null; + }, + prior: (value) => { + let array = value.split(",").map((a) => a.trim()); + if (array.length !== 2) { + return "Toplamı altı olan iki pozitif tamsayı girmeniz bekleniyor."; + } + for (let line of array) { + if ( + !isInDesiredForm(line) || + Number(line) > 5 || + Number(line) < 1 + ) { + return "Toplamı altı olan iki pozitif tamsayı girmeniz bekleniyor."; + } + } + if (Number(array[0]) + Number(array[1]) !== 6) { + return "Toplamı altı olan iki pozitif tamsayı girmeniz bekleniyor."; + } + return null; + }, + }, + }); + + useEffect( + () => { + form.setValues({ name: getDateText() }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + async function sendData(data: { + name: string; + num_of_blue_a: number; + num_of_blue_b: number; + treatment: null; + drawn_balls: string; + }) { + const parsedData = { + ...data, + drawn_balls: data.drawn_balls.split(",").map(Number), + prior: data.drawn_balls.split(",").map(Number), + }; + await fetch( + process.env.NODE_ENV === "production" + ? `./api/admin` + : "../api/admin", + { + method: "POST", + body: JSON.stringify(parsedData), + headers: { Authorization: pass }, + } + ); + router.reload(); + } + return ( @@ -129,6 +225,74 @@ export default function Home({ Save Password + + sendData(data))} + > + + + + + + + + + + + + + + + +
+ +
- + > + Devam + +
); } diff --git a/src/components/gpsComponents/HypoDonation.tsx b/src/components/gpsComponents/HypoDonation.tsx index fc8c39e..387a977 100644 --- a/src/components/gpsComponents/HypoDonation.tsx +++ b/src/components/gpsComponents/HypoDonation.tsx @@ -1,20 +1,59 @@ -import { Button } from "@mantine/core"; +import { Button, Container, Center, Divider } from "@mantine/core"; import type { GpsData } from "../Gps"; +import { useState } from "react"; +import { inflationMultiplier } from "@/utilities/constants"; -function HypoDonation({ setSubphase }: { setSubphase: (subsetOfGps: Partial, lastSubphase: boolean, p: string) => void }) { +function HypoDonation({ + setSubphase, +}: { + setSubphase: ( + subsetOfGps: Partial, + lastSubphase: boolean, + p: string + ) => void; +}) { + const [value, setValue] = useState(""); return ( -
-

hypo

+ +
+
Lütfen aşağıdaki durumu hayal edin:
+

+ Bugün beklenmedik bir şekilde {400 * inflationMultiplier} TL + aldınız. İyi bir amaç için bu miktarın ne kadarını + bağışlarsınız? (0 ile {400 * inflationMultiplier} arasındaki + herhangi bir değeri seçebilirsiniz) +

+
+ +
+ setValue(e.target.value)} + value={value} + required + /> +
+ -
+ > + Devam + + ); } diff --git a/src/components/gpsComponents/StairPatience.tsx b/src/components/gpsComponents/StairPatience.tsx index 725d98c..73b7bb7 100644 --- a/src/components/gpsComponents/StairPatience.tsx +++ b/src/components/gpsComponents/StairPatience.tsx @@ -1,5 +1,16 @@ -import { Button } from "@mantine/core"; +import { + Button, + Container, + Radio, + Group, + Center, + Divider, +} from "@mantine/core"; import type { GpsData } from "../Gps"; +import { useState, useRef } from "react"; +import { inflationMultiplier } from "@/utilities/constants"; + +import customStyles from "@/styles/Custom.module.css"; const stairPatienceMap = new Map(); stairPatienceMap.set(62, [50, 74]); @@ -18,20 +29,127 @@ stairPatienceMap.set(71, [69, 72]); stairPatienceMap.set(77, [76, 79]); stairPatienceMap.set(84, [82, 86]); -function StairPatience({ setSubphase }: { setSubphase: (subsetOfGps: Partial, lastSubphase: boolean) => void }) { +function StairPatience({ + setSubphase, +}: { + setSubphase: (subsetOfGps: Partial, lastSubphase: boolean) => void; +}) { + const [valueNow, setValueNow] = useState(62); + const radioRefA = useRef(null); + const radioRefB = useRef(null); + const stairStepRef = useRef(null); + const stairSelections = useRef([]); + + const [buttonDisabled, setButtonDisabled] = useState(false); + + function nextQuestion() { + if (radioRefA.current !== null && radioRefB.current !== null) { + let nextValue: number; + if (radioRefA.current.checked || radioRefB.current.checked) { + if (radioRefA.current.checked) { + stairSelections.current.push( + Number(radioRefA.current.value) + ); + if (stairPatienceMap.get(valueNow)) { + nextValue = stairPatienceMap.get(valueNow)[1]; + } + } + if (radioRefB.current.checked) { + stairSelections.current.push( + Number(radioRefB.current.value) + ); + if (stairPatienceMap.get(valueNow)) { + nextValue = stairPatienceMap.get(valueNow)[0]; + } + } + setButtonDisabled(true); + if (stairStepRef.current !== null) { + stairStepRef.current.style.opacity = "0"; + } + setTimeout(() => { + if (stairStepRef.current !== null) { + stairStepRef.current.style.opacity = "1"; + } + setValueNow(nextValue); + setButtonDisabled(false); + }, 750); + } else { + radioRefA.current.reportValidity(); + } + } + if (stairSelections.current.length < 5) { + return false; + } + const finalResult = + 33 - + stairSelections.current.reduce( + (prev, curr, index) => prev + curr * (16 / 2 ** index), + 1 + ); + setSubphase({ gps_stair_patience: finalResult }, true); + } return ( -
-

stairpatience

+ +
+

+ Size bugün bir ödeme alma veya 12 ay sonra bir ödeme alma + arasında seçim hakkı verildiğini varsayın. Şimdi size beş + durum sunacağız. Bugünkü ödeme miktarı, bu beş durumun her + birinde aynıdır. 12 ay sonra ödenecek miktar ise her durumda + farklıdır. +

+

+ Bu durumların her biri için hangisini seçeceğinizi bilmek + istiyoruz. Enflasyon olmadığını varsayın, yani gelecekteki + fiyatlar bugünkü fiyatlar ile aynıdır. +

+
+ +
+
+ Lütfen aşağıdaki durumu değerlendirin: +
+

+ Bugün {40 * inflationMultiplier} TL almayı + mı yoksa 12 ay sonra{" "} + {valueNow * inflationMultiplier} TL almayı + mı tercih edersiniz? +

+
+ + + + + + +
+
+ -
+ > + Devam + + ); } diff --git a/src/components/gpsComponents/StairRisk.tsx b/src/components/gpsComponents/StairRisk.tsx index b3ef968..d3faa27 100644 --- a/src/components/gpsComponents/StairRisk.tsx +++ b/src/components/gpsComponents/StairRisk.tsx @@ -9,11 +9,19 @@ import { import { useRef, useState } from "react"; import customStyles from "@/styles/Custom.module.css"; import type { GpsData } from "../Gps"; +import { inflationMultiplier } from "@/utilities/constants"; -const inflationMultiplier = 10; const stair1SureOutcome = 150; -function StairRisk({ setSubphase }: { setSubphase: (subsetOfGps: Partial, lastSubphase: boolean, p: string) => void }) { +function StairRisk({ + setSubphase, +}: { + setSubphase: ( + subsetOfGps: Partial, + lastSubphase: boolean, + p: string + ) => void; +}) { const radioRefA = useRef(null); const radioRefB = useRef(null); const stairStepRef = useRef(null); @@ -25,7 +33,7 @@ function StairRisk({ setSubphase }: { setSubphase: (subsetOfGps: Partial prev + curr * (16 / 2 ** index), 1 ); - setSubphase({}, false,"gift"); + setSubphase({ gps_stair_risk: finalResult }, false, "gift"); } return ( @@ -100,7 +107,6 @@ function StairRisk({ setSubphase }: { setSubphase: (subsetOfGps: Partial @@ -119,12 +125,12 @@ function StairRisk({ setSubphase }: { setSubphase: (subsetOfGps: Partial + - {showNextPhase && ( + {slideIndex === 5 && ( )} diff --git a/src/components/Round.tsx b/src/components/Round.tsx index a17bf33..02129d9 100644 --- a/src/components/Round.tsx +++ b/src/components/Round.tsx @@ -1,4 +1,4 @@ -import { useState, useRef } from "react"; +import { useState, useRef, Dispatch, SetStateAction } from "react"; import Slider from "./experimentComponents/Slider"; import Circles from "./experimentComponents/Circles"; import Drawing from "./experimentComponents/Drawing"; @@ -25,6 +25,8 @@ function Round({ phaseFunction, pointFunction, participantId, + currentRound, + roundFunction, }: { bsr: boolean; arrayOfDraws: number[]; @@ -32,22 +34,23 @@ function Round({ aBlue: number; bBlue: number; phaseFunction: (p: Phase) => void; - pointFunction: (p: number) => void; + pointFunction: Dispatch>; participantId: string; + currentRound: number; + roundFunction: (r: number) => void; }) { const [redRatio, setRedRatio] = useState(50); - const [currentRound, setCurrentRound] = useState(0); const [selectedBag, setSelectedBag] = useState<"blue" | "red">( - Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" : "red" + Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" : "red", ); const roundData = useRef>({ is_blue: selectedBag === "blue", }); const [subPhase, setSubPhase] = useState<"drawing" | "input" | "result">( - "drawing" + "drawing", ); - const [point, setPoint] = useState(0); const time = useRef(new Date()); + const [pointsForCurrentRound, setPointsForCurrentRound] = useState(0); const numberOfRounds = arrayOfDraws.length; const diceText = getDiceText(priors); @@ -76,16 +79,8 @@ function Round({ setSubPhase("input"); } - function calculatePointsForRound() { - if (selectedBag === "blue") { - return (100 - redRatio) ** 2; - } else { - return redRatio ** 2; - } - } - async function generateNewRound(lastRound: Omit) { - const respond = await fetch("./api/round", { + await fetch("./api/round", { method: "POST", body: JSON.stringify(lastRound), }); @@ -94,33 +89,29 @@ function Round({ function nextRound() { const lastRound: Omit = { ...(roundData.current as SubTypeRound), - participantId: participantId, + participantId, chosen_probability: 100 - redRatio, - reward: calculatePointsForRound(), + reward: pointsForCurrentRound, round: currentRound + 1, }; console.log(lastRound); generateNewRound(lastRound); - setPoint(calculatePointsForRound() + point); - pointFunction(calculatePointsForRound() + point); + pointFunction((p: number) => p + pointsForCurrentRound); if (currentRound < numberOfRounds - 1) { const newBag = - Math.random() < priors[0] / (priors[0] + priors[1]) - ? "blue" - : "red"; + Math.random() < priors[0] / (priors[0] + priors[1]) ? "blue" : "red"; setSelectedBag(newBag); setSubPhase("drawing"); roundData.current = { ...roundData.current, is_blue: newBag === "blue" ? true : false, }; - setCurrentRound(currentRound + 1); + roundFunction(currentRound + 1); setRedRatio(50); time.current = new Date(); } else { phaseFunction(Phase.Demographics); - pointFunction(point); } } @@ -153,6 +144,7 @@ function Round({ value={redRatio} showResult={subPhase === "result"} chooseCircle={selectedBag} + setCurrentPoints={setPointsForCurrentRound} style={{ gap: "10ch", justifyContent: "center", @@ -162,7 +154,7 @@ function Round({ {subPhase === "result" && (
- {`${calculatePointsForRound()} kazandınız.`} + {`${pointsForCurrentRound} kazandınız.`}
)} {(subPhase === "input" || subPhase === "result") && ( diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index 9501cdd..1f7e986 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -1,18 +1,86 @@ import customStyles from "@/styles/Custom.module.css"; +import { GpsQuestion } from "@/utilities/types"; +import { Stepper } from "@mantine/core"; +import { Phase } from "@/utilities/types"; const phaseName = new Map(); -phaseName.set("INTRO", "Giriş"); +phaseName.set("INTRO", "Karşılama"); phaseName.set("INTRO2", "Giriş"); -phaseName.set("MAIN", "Giriş"); +phaseName.set("MAIN", "Deney"); phaseName.set("END", "Sonuç"); -phaseName.set("DEMO", "Anket-1"); -phaseName.set("GPS", "Anket-2"); +phaseName.set("DEMO", "Anket"); +phaseName.set("GPS", "Anket"); -function TopBar({ phase, points }: { phase: string; points: number }) { +const allGpsQuestions = [ + `generalrisk`, + `willingnesstoact`, + `describe`, + `stairrisk`, + `gift`, + `hypodonation`, + `stairpatience`, +]; + +const allStepperPhases = ["Karşılama", "Giriş", "Deney", "Anket"]; + +function TopBar({ + phase, + points, + currentRound, + lastRound, + currentQuestion, +}: { + phase: Phase; + points: number; + currentRound: number; + lastRound: number; + currentQuestion: GpsQuestion; +}) { + const activeStep = + allStepperPhases.indexOf(phaseName.get(phase)) >= 0 + ? allStepperPhases.indexOf(phaseName.get(phase)) + : 4; return (
-
{phaseName.get(phase)}
-
Toplam puan: {points}
+
+ {} + + + + +
+
Toplam puan: {points}
+
+
+ + +
+
Deney Bitti. Kazandığınız toplam puan: {points}
+
+ Kazandığınız toplam para: {30 + Math.round(points / 1000)} TL +
+
+
+
+
); } diff --git a/src/components/experimentComponents/BagHolder.tsx b/src/components/experimentComponents/BagHolder.tsx index e34a0ef..abe6f79 100644 --- a/src/components/experimentComponents/BagHolder.tsx +++ b/src/components/experimentComponents/BagHolder.tsx @@ -17,9 +17,8 @@ function BagHolder({
- Kırmızı Torba:{" "} - {aBlue} adet{" "} - mavi bilye,{" "} + Kırmızı Torba: {aBlue}{" "} + adet mavi bilye,{" "} {100 - aBlue} adet{" "} kırmızı bilye @@ -39,9 +38,8 @@ function BagHolder({
- Mavi Torba:{" "} - {bBlue} adet{" "} - mavi bilye,{" "} + Mavi Torba: {bBlue}{" "} + adet mavi bilye,{" "} {100 - bBlue} adet{" "} kırmızı bilye diff --git a/src/components/experimentComponents/Circle.tsx b/src/components/experimentComponents/Circle.tsx new file mode 100644 index 0000000..c03236c --- /dev/null +++ b/src/components/experimentComponents/Circle.tsx @@ -0,0 +1,62 @@ +import styles from "@/styles/Circles.module.css"; +import clsx from "clsx"; +import { XIcon } from "./XIcon"; + +const Circle = ({ + value, + color, + bsr, + crossCoordinates, + showResult, +}: { + value: number; + color: "red" | "blue"; + bsr: boolean; + crossCoordinates: { + x: number; + y: number; + } | null; + showResult: boolean; +}) => { + const bigCircleClasses = clsx( + styles.bigCircle, + styles.circle, + value === 0 && styles.invis, + color === "red" && styles.red, + color === "blue" && styles.blue, + ); + + const smallCircleClasses = clsx( + styles.circle, + styles.white, + styles.smallCircle, + ); + + return ( +
+
+ {bsr && crossCoordinates !== null && showResult && ( +
+ +
+ )} + {!bsr &&

{10000 - (100 - value) ** 2}

} + {/* {bsr &&

{value / 10000}

} */} +
+ ); +}; + +export default Circle; diff --git a/src/components/experimentComponents/Circles.tsx b/src/components/experimentComponents/Circles.tsx index 9c22cc0..a3b1c63 100644 --- a/src/components/experimentComponents/Circles.tsx +++ b/src/components/experimentComponents/Circles.tsx @@ -1,130 +1,95 @@ -import { useRef, useEffect } from "react"; +import { useRef, useEffect, useState, Dispatch, SetStateAction } from "react"; import styles from "@/styles/Circles.module.css"; import autoAnimate from "@formkit/auto-animate"; +import Circle from "./Circle"; + +function radiusOfWhiteCircle(type: "red" | "blue", value: number) { + if (type === "red") { + return (300 - Number(value) * 3) / 2; + } else { + return (300 - Number(100 - value) * 3) / 2; + } +} function Circles({ value, bsr, showResult, chooseCircle, + setCurrentPoints = false, style, }: { value: number; bsr: boolean; showResult: boolean; chooseCircle: "blue" | "red"; + setCurrentPoints?: Dispatch> | false; style?: React.CSSProperties; }) { const parent = useRef(null); + const [crossCoordinates, setCrossCoordinates] = useState<{ + x: number; + y: number; + } | null>(null); + const [showBlue, showRed] = [ !showResult || chooseCircle === "blue", !showResult || chooseCircle === "red", ]; - // const [show,setShow] = useState([true,true]); useEffect(() => { parent.current && autoAnimate(parent.current); }, [parent]); - function addInvis(target: number) { - //this ensures that no clipping remains in the full probabilities. - if (value === target) { - return ` ${styles.invis}`; - } else { - return ""; - } - } + useEffect(() => { + const calculatePointsForRound = (value: number) => { + if (bsr) { + const distance = chooseARandomPoint(); + let point = + radiusOfWhiteCircle(chooseCircle, value) > distance ? 0 : 10000; - function addCorrectMark( - colorOfThis: "blue" | "red", - thresholdForSmallCircle?: number - ) { - if ( - showResult && - ((chooseCircle === colorOfThis && - thresholdForSmallCircle === undefined) || - (chooseCircle === colorOfThis && - value !== thresholdForSmallCircle)) - ) { - // if ( - // (chooseCircle === colorOfThis && thresholdForSmallCircle === undefined) || - // (chooseCircle === colorOfThis && value !== thresholdForSmallCircle) - // ) { - // return ` ${styles.correctAnswer}`; - return ""; - // } - // else { - // return ` ${styles.invis}`; - // } - } else { - return ""; + setCurrentPoints && setCurrentPoints(point); + } else { + if (chooseCircle === "blue") { + setCurrentPoints && setCurrentPoints(10000 - value ** 2); + } else { + setCurrentPoints && setCurrentPoints(10000 - (100 - value) ** 2); + } + } + }; + if (showResult) { + calculatePointsForRound(value); } + }, [bsr, chooseCircle, setCurrentPoints, showResult, value]); + + function chooseARandomPoint() { + const angle = Math.random() * Math.PI * 2; + const dist = Math.sqrt(Math.random()) * 150; + const x = Math.cos(angle) * dist + 150; + const y = Math.sin(angle) * dist + 150; + setCrossCoordinates({ x, y }); + return dist; } return (
{showRed && ( -
-
-

{value ** 2}

-
+ )} {showBlue && ( -
-
-

{(100 - value) ** 2}

-
+ )}
); diff --git a/src/components/experimentComponents/Drawing.tsx b/src/components/experimentComponents/Drawing.tsx index dfbcf94..a3067b4 100644 --- a/src/components/experimentComponents/Drawing.tsx +++ b/src/components/experimentComponents/Drawing.tsx @@ -40,36 +40,24 @@ function Drawing({ const draws = useRef( Array.from({ length: numberOfDraws }, () => - Math.floor(Math.random() * 100) - ).map((num) => (num < numberofBlues ? "blue" : "red")) + Math.floor(Math.random() * 100), + ).map((num) => (num < numberofBlues ? "blue" : "red")), ); function nextSubPhase() { nextFunction({ first_draw_blue: - draws.current[0] === undefined - ? null - : draws.current[0] === "blue", + draws.current[0] === undefined ? null : draws.current[0] === "blue", second_draw_blue: - draws.current[1] === undefined - ? null - : draws.current[1] === "blue", + draws.current[1] === undefined ? null : draws.current[1] === "blue", third_draw_blue: - draws.current[2] === undefined - ? null - : draws.current[2] === "blue", + draws.current[2] === undefined ? null : draws.current[2] === "blue", fourth_draw_blue: - draws.current[3] === undefined - ? null - : draws.current[3] === "blue", + draws.current[3] === undefined ? null : draws.current[3] === "blue", fifth_draw_blue: - draws.current[4] === undefined - ? null - : draws.current[4] === "blue", + draws.current[4] === undefined ? null : draws.current[4] === "blue", sixth_draw_blue: - draws.current[5] === undefined - ? null - : draws.current[5] === "blue", + draws.current[5] === undefined ? null : draws.current[5] === "blue", }); } @@ -77,11 +65,11 @@ function Drawing({ <> {fullView && ( <> -

Çekilen toplar:

+

Çekilen bilyeler:

{numberOfDraws > 0 - ? `Bu turda ${numberOfDraws} top çekilecek.` - : `Bu turda hiç top çekilmeyecek.`} + ? `Bu turda ${numberOfDraws} bilye çekilecek.` + : `Bu turda hiç bilye çekilmeyecek.`}

)} diff --git a/src/components/experimentComponents/XIcon.tsx b/src/components/experimentComponents/XIcon.tsx new file mode 100644 index 0000000..95941e7 --- /dev/null +++ b/src/components/experimentComponents/XIcon.tsx @@ -0,0 +1,16 @@ +export function XIcon({ width, height }: { width: number; height: number }) { + return ( + + + + + + + + ); +} diff --git a/src/components/gpsComponents/Describe.tsx b/src/components/gpsComponents/Describe.tsx index 38c2070..849f790 100644 --- a/src/components/gpsComponents/Describe.tsx +++ b/src/components/gpsComponents/Describe.tsx @@ -1,6 +1,7 @@ import { Button, Container, Radio, Divider } from "@mantine/core"; import type { GpsData } from "../Gps"; import { useState } from "react"; +import type { GpsQuestion } from "@/utilities/types"; function Describe({ setSubphase, @@ -8,7 +9,7 @@ function Describe({ setSubphase: ( subsetOfGps: Partial, lastSubphase: boolean, - p: string + p: GpsQuestion, ) => void; }) { const [value1, setValue1] = useState(undefined); @@ -20,10 +21,10 @@ function Describe({

Aşağıdaki ifadelerden her biri sizi ne kadar iyi tanımlar?

- Lütfen cevabınızı 0'dan 10'a kadar bir ölçekte belirtin. - 0 “beni hiç ifade etmiyor” ve 10 “beni mükemmel şekilde ifade - ediyor” anlamına gelir. Ölçekte nereye düştüğünüzü belirtmek - için 0 ile 10 arasında herhangi bir sayı kullanabilirsiniz. + Lütfen cevabınızı 0'dan 10'a kadar bir ölçekte belirtin. 0 “beni + hiç ifade etmiyor” ve 10 “beni mükemmel şekilde ifade ediyor” anlamına + gelir. Ölçekte nereye düştüğünüzü belirtmek için 0 ile 10 arasında + herhangi bir sayı kullanabilirsiniz.

@@ -34,12 +35,8 @@ function Describe({ value={value1} onChange={setValue1} > -
- +
+ @@ -49,10 +46,7 @@ function Describe({ - +
@@ -63,12 +57,8 @@ function Describe({ value={value2} onChange={setValue2} > -
- +
+ @@ -78,10 +68,7 @@ function Describe({ - +
@@ -92,12 +79,8 @@ function Describe({ value={value3} onChange={setValue3} > -
- +
+ @@ -107,10 +90,7 @@ function Describe({ - +
@@ -121,12 +101,8 @@ function Describe({ value={value4} onChange={setValue4} > -
- +
+ @@ -136,10 +112,7 @@ function Describe({ - +
@@ -150,12 +123,8 @@ function Describe({ value={value5} onChange={setValue5} > -
- +
+ @@ -165,10 +134,7 @@ function Describe({ - +
+
+ 0.5 ? "blue" : "red"} + /> +
+ + ); +}; + +export default Slide6BSR; diff --git a/src/components/intro2Components/Slide6QSR.tsx b/src/components/intro2Components/Slide6QSR.tsx new file mode 100644 index 0000000..4d83bc0 --- /dev/null +++ b/src/components/intro2Components/Slide6QSR.tsx @@ -0,0 +1,56 @@ +import Circles from "../experimentComponents/Circles"; +import Slider from "../experimentComponents/Slider"; +import customStyles from "@/styles/Custom.module.css"; +import circleStyles from "@/styles/Circles.module.css"; +import { List } from "@mantine/core"; +import { Carousel } from "@mantine/carousel"; +import { useState } from "react"; + +const Slide6QSR = () => { + const [sliderValue, setSliderValue] = useState(50); + return ( + + + + Karar ekranında, bahsettiğimiz kaydırıcının tam altında kırmızı ve + mavi birer simit olacak. Kaydırıcıyı sağa yahut sola sürükledikçe + kırmızı simidin ve mavi simidin büyüklüklerinin değiştiğini + görebilirsiniz. Daha büyük bir simit daha çok puana karşılık gelir. Bu + puan simidin ortasında yazar. + + + Karar verdikten sonra, gerçekte hangi torbanın kullanıldığı size + bildirilecektir. Şayet o turda{" "} + Kırmızı torba kullanılmış ise, + kazancınız kırmızı simidin karşılık geldiği miktar olacak. Şayet o + turda Mavi torba kullanılmış + ise, kazancınız mavi simidin karşılık geldiği miktar olacak. + + +
+
+ { + setSliderValue(Number(event.target.value)); + }} + /> +
+ +
+
+ ); +}; + +export default Slide6QSR; diff --git a/src/database/index.ts b/src/database/index.ts index 072b9a6..901f3a0 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -1,19 +1,3 @@ import { PrismaClient } from "@prisma/client"; export const prisma = new PrismaClient(); - -// async function main() { -// // ... you will write your Prisma Client queries here -// const sessionData = await prisma.session.findFirst(); -// console.log(sessionData) -// } - -// main() -// .then(async () => { -// await prisma.$disconnect() -// }) -// .catch(async (e) => { -// console.error(e) -// await prisma.$disconnect() -// process.exit(1) -// }) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 7fc543d..4041bbb 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -2,6 +2,7 @@ import { AppProps } from "next/app"; import Head from "next/head"; import { MantineProvider } from "@mantine/core"; import "@/styles/globals.css"; +import buildDate from "../../buildDate"; export default function App(props: AppProps) { const { Component, pageProps } = props; @@ -11,18 +12,13 @@ export default function App(props: AppProps) { <> Ekonomi Deneyi - + + - + (
- + )); return ( diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 04a14de..70ba24e 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -36,25 +36,22 @@ export default function Home({ useDisclosure(false); async function downloadData( - listOfSessions: string[] = selectedSessions.map((a) => a.id) + listOfSessions: string[] = selectedSessions.map((a) => a.id), ) { let res = ""; if (data.length > selectedSessions.length) { res = "?" + - Object.entries(listOfSessions) - .map(([k, v]) => `sessionId=${v}`) - .join("&"); + listOfSessions.map((sessionId) => `sessionId=${sessionId}`).join("&"); } - console.log(pass); const respond = await fetch( process.env.NODE_ENV === "production" - ? `./api/round` + ? `./api/round` + res : "../api/round" + res, { method: "GET", headers: { Authorization: pass }, - } + }, ); const columnNames = [ @@ -127,7 +124,7 @@ export default function Home({ name: "", num_of_blue_a: 30, num_of_blue_b: 70, - treatment: null, + treatment: "", drawn_balls: "", prior: "3,3", }, @@ -151,11 +148,7 @@ export default function Home({ return "Toplamı altı olan iki pozitif tamsayı girmeniz bekleniyor."; } for (let line of array) { - if ( - !isInDesiredForm(line) || - Number(line) > 5 || - Number(line) < 1 - ) { + if (!isInDesiredForm(line) || Number(line) > 5 || Number(line) < 1) { return "Toplamı altı olan iki pozitif tamsayı girmeniz bekleniyor."; } } @@ -172,30 +165,29 @@ export default function Home({ form.setValues({ name: getDateText() }); }, // eslint-disable-next-line react-hooks/exhaustive-deps - [] + [], ); async function sendData(data: { name: string; num_of_blue_a: number; num_of_blue_b: number; - treatment: null; + treatment: string; drawn_balls: string; + prior: string; }) { const parsedData = { ...data, drawn_balls: data.drawn_balls.split(",").map(Number), - prior: data.drawn_balls.split(",").map(Number), + prior: data.prior.split(",").map(Number), }; await fetch( - process.env.NODE_ENV === "production" - ? `./api/admin` - : "../api/admin", + process.env.NODE_ENV === "production" ? `./api/admin` : "../api/admin", { method: "POST", body: JSON.stringify(parsedData), headers: { Authorization: pass }, - } + }, ); router.reload(); } @@ -225,11 +217,7 @@ export default function Home({ Save Password - + sendData(data))} @@ -299,8 +287,7 @@ export default function Home({ disabled={!selectedSessions.length} onClick={() => downloadData()} > - {!selectedSessions.length && - `Verisi indirilecek oturumları seçin.`} + {!selectedSessions.length && `Verisi indirilecek oturumları seçin.`} {selectedSessions.length > 0 && `Seçili oturumların verisini indirin.`} @@ -319,7 +306,7 @@ export default function Home({ router.push( process.env.NODE_ENV === "production" ? `./belief/admin/${session.id}` - : `./admin/${session.id}` + : `./admin/${session.id}`, ); }} /> @@ -331,12 +318,13 @@ export const getServerSideProps: GetServerSideProps<{ data: Session[]; }> = async () => { let allSessions = (await prisma.session.findMany()) as Session[]; - allSessions = allSessions.map((a) => ({ - ...a, - start_time: JSON.parse(JSON.stringify(a?.start_time)), - end_time: JSON.parse(JSON.stringify(a?.end_time)), - })); - + allSessions = allSessions + .sort((a, b) => b.start_time.getTime() - a.start_time.getTime()) + .map((a) => ({ + ...a, + start_time: JSON.parse(JSON.stringify(a?.start_time)), + end_time: JSON.parse(JSON.stringify(a?.end_time)), + })); return { props: { data: allSessions as Session[], diff --git a/src/pages/api/admin.ts b/src/pages/api/admin.ts index 959f6be..01a7c0c 100644 --- a/src/pages/api/admin.ts +++ b/src/pages/api/admin.ts @@ -4,7 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; export default async function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse, ) { if (req.method === "POST") { if (req.headers?.authorization !== process.env.ADMIN_PASS) { diff --git a/src/pages/api/hello.ts b/src/pages/api/hello.ts index 68275d6..b65617f 100644 --- a/src/pages/api/hello.ts +++ b/src/pages/api/hello.ts @@ -7,7 +7,7 @@ type Data = { export default function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse, ) { res.status(200).json({ name: "John Doe" }); } diff --git a/src/pages/api/participant.ts b/src/pages/api/participant.ts index 3157879..9ca3359 100644 --- a/src/pages/api/participant.ts +++ b/src/pages/api/participant.ts @@ -4,7 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; export default async function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse, ) { if (req.method === "POST") { const { body } = req; diff --git a/src/pages/api/participant/[id].ts b/src/pages/api/participant/[id].ts index 1f8c348..6e04c4a 100644 --- a/src/pages/api/participant/[id].ts +++ b/src/pages/api/participant/[id].ts @@ -4,11 +4,14 @@ import type { NextApiRequest, NextApiResponse } from "next"; export default async function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse, ) { if (req.method === "PUT") { const { body } = req; const { id } = req.query; + if (id === "no-id-given") { + return res.status(200).json({ message: "test" }); + } try { if (typeof id === "string") { const updateUser = await prisma.participant.update({ @@ -17,6 +20,9 @@ export default async function handler( }, data: JSON.parse(body), }); + if (!updateUser) { + return res.status(404); + } return res.status(200).json(updateUser); } diff --git a/src/pages/api/round.ts b/src/pages/api/round.ts index 13112bc..47dff64 100644 --- a/src/pages/api/round.ts +++ b/src/pages/api/round.ts @@ -7,8 +7,8 @@ export interface RoundToDownload extends Round, Session, Participant {} export default async function handler( req: NextApiRequest, res: NextApiResponse< - Round | Omit[] - > + null | Round | Omit[] + >, ) { if (req.method === "POST") { const { body } = req; @@ -73,7 +73,7 @@ function flattenRound( Participant: Participant & { Session: Session; }; - } + }, ) { const { Participant, Session, ...rest } = { ...round.Participant, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index a113993..4bf69a2 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,17 +1,12 @@ -// import Head from "next/head"; - -// import { reducer, StateProvider } from "../state"; import Experiment from "@/components/Experiment"; import { InferGetServerSidePropsType } from "next"; import { GetServerSideProps } from "next"; import { prisma } from "@/database"; import { Session } from "@prisma/client"; - export default function Home({ data, }: InferGetServerSidePropsType) { - // console.log(data) return ; } @@ -20,7 +15,6 @@ export interface SessionType extends Omit { } const defaultSession: Omit = { - // id: 'placeholderSession', start_time: new Date(), end_time: null, name: "alpha_1", @@ -35,22 +29,20 @@ const defaultSession: Omit = { export const getServerSideProps: GetServerSideProps<{ data: SessionType; }> = async () => { - let sessionData = ( - await prisma.session.findMany({ - take: -1, - }) - )[0]; + let sessionData = await prisma.session.findFirst({ + orderBy: { + start_time: "desc", + }, + }); - console.log(sessionData); if (sessionData === null) { sessionData = await prisma.session.create({ data: { ...defaultSession }, }); } - sessionData.start_time = JSON.parse( - JSON.stringify(sessionData?.start_time) - ); + sessionData.start_time = JSON.parse(JSON.stringify(sessionData?.start_time)); sessionData.end_time = JSON.parse(JSON.stringify(sessionData?.end_time)); + sessionData.drawn_balls = shuffle(sessionData.drawn_balls); return { props: { @@ -58,3 +50,12 @@ export const getServerSideProps: GetServerSideProps<{ }, }; }; + +function shuffle(array: number[]) { + let resArray = array; + for (let i = resArray.length - 1; i > 0; i--) { + let j = Math.floor(Math.random() * (i + 1)); + [resArray[i], resArray[j]] = [resArray[j], resArray[i]]; + } + return resArray; +} diff --git a/src/styles/Circles.module.css b/src/styles/Circles.module.css index 7ef7504..12f4e4d 100644 --- a/src/styles/Circles.module.css +++ b/src/styles/Circles.module.css @@ -4,10 +4,6 @@ padding: 2rem; } -/* .circleHolder>*{ - outline: green 2px solid; -} */ - .padding-left { padding-left: 2vw; } @@ -84,17 +80,18 @@ .smallestCircle { position: absolute; z-index: 4; - width: 0px; - height: 0px; + width: 18px; + height: 18px; + animation: fadein 2s ease-in; } -.smallestCircle:after { - content: "\00d7"; - font-size: 1.9rem; - top: 50%; - left: 10%; - display: inline-block; - transform: translate(-50%, -50%); +@keyframes fadein { + from { + opacity: 0; + } + to { + opacity: 1; + } } .circleHolder, @@ -161,21 +158,13 @@ button.exp { .invis.red, .invis.white { background-color: rgba(0, 0, 0, 0); - /* display: none; */ -} - -/* .correctAnswer { - outline: 5px gold solid; -} */ - -.inCorrectAnswer { - display: none; } .valueBox { position: absolute; - bottom: -40px; + top: 150px; + z-index: 3; left: 150px; - transform: translateX(-50%); + transform: translate(-50%, -50%); font-size: 20px; } diff --git a/src/styles/Custom.module.css b/src/styles/Custom.module.css index a3f3b54..edce493 100644 --- a/src/styles/Custom.module.css +++ b/src/styles/Custom.module.css @@ -1,19 +1,15 @@ .entryText { text-align: left; - font-size: 1.5rem; + font-size: 1.25rem; max-width: 75ch; padding-inline: 2ch; - margin: 5.5rem auto 1rem auto; + margin: 3.5rem auto 1rem auto; } .entryText > li + li { margin-top: 0.75em; } -/* .mantine-List-item{ - list-style-position: inside !important; -} */ - .mainWrapper { max-width: 1200px; } @@ -33,11 +29,6 @@ padding: 0.6rem 1.1rem; } -/* .debug { - position: absolute; - left: 5px; -} */ - .ballText { text-align: center; font-size: 1.5rem; @@ -52,8 +43,6 @@ .bagHolder { display: flex; gap: 10%; - /* margin: 5% 10%; */ - /* margin-bottom: 10ch; */ margin-inline: auto; width: 1000px; justify-content: center; @@ -61,14 +50,11 @@ .bagHolder > * { padding: 2ch; - /* margin-inline:auto; */ - /* text-align: center; */ - /* width: 26ch; */ } -/* div.__className_4b5723:nth-child(1) > div */ + .bagHolder > :nth-child(1) > :not(:last-child), .bagHolder > :nth-child(2) > :not(:last-child) { - margin-bottom: 2ch; + margin-bottom: 1.5ch; } .bagHolder > :nth-child(2) { @@ -93,41 +79,27 @@ margin: 3ch; text-align: center; margin-top: 5ch; + -webkit-animation: fadeIn 3s; + animation: fadeIn 3s; } -.footer { - position: fixed; - width: 100%; - bottom: 0px; - /* top: calc(100% - 56px); */ - height: 55px; - left: 0px; - text-align: right; - font-weight: 800; - padding: 20px; - padding-bottom: 20px; - padding-right: calc(50vw - 600px); - box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; - background-color: rgb(226, 241, 247); - margin-top: auto; -} - -.footer > a { - color: rgb(47, 47, 203); +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } } .topbar { - position: fixed; - left: 0px; - top: 0px; - width: 100%; - background-color: rgb(226, 241, 247); - box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px; + width: 100vw; margin-top: 0px; padding: 1ch 5ch; display: flex; gap: 3ch; z-index: 300; + box-shadow: 0 4px 2px -2px rgb(203, 203, 203); } .stairStep { diff --git a/src/styles/Demographics.module.css b/src/styles/Demographics.module.css deleted file mode 100644 index 14461a9..0000000 --- a/src/styles/Demographics.module.css +++ /dev/null @@ -1,45 +0,0 @@ -.label { - display: block; - font-size: 14px; - font-weight: bold; - padding: 18px 0 0 0; - margin-bottom: 10px; -} -.likert { - list-style: none; - width: 100%; - margin: 0; - padding: 0 0 35px; - display: block; - border-bottom: 2px solid #efefef; -} -.likert:last-of-type { - border-bottom: 0; -} -.likert:before { - content: ""; - position: relative; - top: 11px; - left: 5%; - display: block; - background-color: #efefef; - height: 4px; - width: 80%; -} -.likert li { - display: inline-block; - width: 8%; - text-align: center; - vertical-align: top; -} -.likert li input[type="radio"] { - display: block; - position: relative; - top: 0; - left: 50%; - margin-left: -6px; -} - -div .likert li label { - width: 100%; -} diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css index bc48390..5557205 100644 --- a/src/styles/Home.module.css +++ b/src/styles/Home.module.css @@ -1,9 +1,12 @@ .main { display: flex; flex-direction: column; - justify-content: space-between; + /* justify-content: space-between; */ + justify-content: flex-start; + gap: 0.5rem; align-items: center; - padding: 6rem; + padding: 1rem; + padding-top: 0px; min-height: 100vh; /* font-size: 14px; */ } diff --git a/src/styles/globals.css b/src/styles/globals.css index 58d162a..04688ee 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,7 +1,7 @@ :root { --max-width: 1100px; --border-radius: 12px; - font-size: 14px; + font-size: 18px; --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace; @@ -72,21 +72,33 @@ a { text-decoration: none; } +.mantine-RadioGroup-root.likert > .mantine-Group-root { + column-gap: 0; +} + +.mantine-RadioGroup-root.likert { + text-align: center; +} .mantine-RadioGroup-root.likert .mantine-Radio-body { flex-direction: column; justify-content: center; + align-content: center; } .mantine-RadioGroup-root.likert .mantine-Radio-root { margin-top: 5px; align-self: flex-start; - width: 35px; + width: 9%; } .mantine-RadioGroup-root.likert { position: relative; } +.mantine-RadioGroup-root.likert label.mantine-Radio-label { + padding-left: 0; +} + .mantine-RadioGroup-root.likert .mantine-Radio-inner { margin-inline: auto; } @@ -94,55 +106,59 @@ a { .mantine-RadioGroup-root.likert .mantine-Group-root:before { content: ""; position: absolute; - top: 44px; - left: 10px; + top: 3rem; + margin-inline: auto; display: block; background-color: #efefef; height: 4px; - width: 500px; + width: 90%; + left: 50%; + transform: translateX(-50%); } /* GPS */ .likertDiv { display: flex; position: relative; - height: 120px; + margin-top: 40px; + width: min(60rem, 80vw); + justify-content: center; } .likertDiv .mantine-Radio-body { flex-direction: column; justify-content: center; - width: 50px; align-items: center; } -.likertDiv .mantine-Radio-inner { - margin-inline: auto; +.likertDiv .mantine-Radio-root { + width: 8%; } -.likertDiv .mantine-Radio-labelWrapper { - position: relative; +.likertDiv .mantine-Radio-inner { + align-self: center; } + .likertDiv label { - position: absolute; - width: 80px; padding-left: 0px; - left: -40px; text-align: center; + margin-inline: -20px; +} + +.likertDiv.extraMargin label { + margin-inline: -25px; } .likertDiv:after { content: ""; position: absolute; - top: 6px; - left: 20px; + top: 9px; + padding-inline: auto; display: block; background-color: #efefef; height: 4px; - width: 500px; z-index: -1; -} - -.shortLikert { - height: 90px; + width: 80%; + left: 50%; + transform: translateX(-50%); } diff --git a/src/utilities/functions.ts b/src/utilities/functions.ts index 086e0b6..a4d675d 100644 --- a/src/utilities/functions.ts +++ b/src/utilities/functions.ts @@ -9,7 +9,7 @@ function arrayToCsv(data: RoundToDownload[], columnNames: string[]): string { .map(String) // convert every value to String .map((v) => v.replaceAll('"', '""')) // escape double colons .map((v) => `"${v}"`) // quote it - .join(",") // comma-separated + .join(","), // comma-separated ) .join("\r\n"); // rows starting on new lines } @@ -28,16 +28,16 @@ function downloadBlob(content: string, filename: string, contentType: string) { export function downloadDataAsCsv( data: RoundToDownload[], - columnNames: string[] + columnNames: string[], ) { downloadBlob( arrayToCsv(data, columnNames), `${new Date()}.csv`, - "text/csv;charset=utf-8;" + "text/csv;charset=utf-8;", ); } -export function getDiceText(prior: [number, number]): [String, String] { +export function getDiceText(prior: [number, number]): [string, string] { const formatter = new Intl.ListFormat("tr", { style: "long", type: "disjunction", diff --git a/src/utilities/types.ts b/src/utilities/types.ts index e250fd0..9c6f340 100644 --- a/src/utilities/types.ts +++ b/src/utilities/types.ts @@ -1,6 +1,7 @@ -export const enum Phase { +export enum Phase { Intro = "INTRO", Intro2 = "INTRO2", + // Trial = "TRIAL", Main = "MAIN", Demographics = "DEMO", Gps = "GPS", @@ -15,3 +16,12 @@ export interface DrawingT { fifth_draw_blue: boolean | null; sixth_draw_blue: boolean | null; } + +export type GpsQuestion = + | `generalrisk` + | `willingnesstoact` + | `describe` + | `stairrisk` + | `gift` + | `hypodonation` + | `stairpatience`;
Kişi adı
{participant.name_surname} - {participant.Round.reduce((acc, curr) => acc + curr.reward, 0)} - {participant.Round.reduce((acc, curr) => acc + curr.reward, 0)}