diff --git a/next.config.js b/next.config.js index a843cbe..79ab98a 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,9 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, -} + images: { + domains: ["avatars.githubusercontent.com"], + }, +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json index 6efdc61..9ccf34c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,11 @@ "nostr-tools": "^1.7.4", "react": "18.2.0", "react-calendar-heatmap": "^1.9.0", + "react-chartjs-2": "^5.2.0", "react-dom": "18.2.0", + "react-qr-code": "^2.0.11", "react-redux": "^8.0.5", + "recharts": "^2.5.0", "redux-thunk": "^2.4.2" } }, @@ -1553,6 +1556,12 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, "node_modules/@next/env": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.2.4.tgz", @@ -2117,6 +2126,60 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/d3-array": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.4.tgz", + "integrity": "sha512-nwvEkG9vYOc0Ic7G7kwgviY4AQlTfYGIZ0fqB7CQHXGyYM6nO7kJh5EguSNA3jfh4rq7Sb7eMVq8isuvg2/miQ==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", + "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -2644,6 +2707,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.1.tgz", + "integrity": "sha512-6YbpQ0nt3NovAgOzbkSSeeAQu/3za1319dPUQTXn9WcOpywM8rGKxJHrhS8V8xEkAlk8YhEfjbuAPfUyp6jIsw==", + "peer": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": "^7.0.0" + } + }, "node_modules/cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2653,6 +2728,11 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -2771,11 +2851,126 @@ "tiny-invariant": "^1.0.6" } }, + "node_modules/css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "node_modules/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -2797,6 +2992,11 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/deep-equal": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz", @@ -2892,6 +3092,14 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -3448,11 +3656,21 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-equals": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", + "integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==" + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -4011,6 +4229,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -4454,6 +4680,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5015,6 +5246,11 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, "node_modules/preact": { "version": "10.13.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.1.tgz", @@ -5085,6 +5321,11 @@ "node": ">=6" } }, + "node_modules/qr.js": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", + "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5127,6 +5368,15 @@ "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-clientside-effect": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", @@ -5182,6 +5432,29 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-qr-code": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.11.tgz", + "integrity": "sha512-P7mvVM5vk9NjGdHMt4Z0KWeeJYwRAtonHTghZT2r+AASinLUUKQ9wfsGH2lPKsT++gps7hXmaiMGRvwTDEL9OA==", + "dependencies": { + "prop-types": "^15.8.1", + "qr.js": "0.0.0" + }, + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x", + "react-native-svg": "*" + }, + "peerDependenciesMeta": { + "react-native-svg": { + "optional": true + } + } + }, "node_modules/react-redux": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", @@ -5270,6 +5543,32 @@ } } }, + "node_modules/react-resize-detector": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.0.4.tgz", + "integrity": "sha512-ln9pMAob8y8mc9UI4aZuuWFiyMqBjnTs/sxe9Vs9dPXUjwCTeKK1FP8I75ufnb/2mEEZXG6wOo/fjMcBRRuAXw==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-smooth": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.2.tgz", + "integrity": "sha512-pgqSp1q8rAGtF1bXQE0m3CHGLNfZZh5oA5o1tsPLXRHnKtkujMIJ8Ws5nO1mTySZf1c4vgwlEk+pHi3Ln6eYLw==", + "dependencies": { + "fast-equals": "^4.0.3", + "react-transition-group": "2.9.0" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -5292,6 +5591,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dependencies": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -5305,6 +5619,47 @@ "node": ">= 6" } }, + "node_modules/recharts": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.5.0.tgz", + "integrity": "sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ==", + "dependencies": { + "classnames": "^2.2.5", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-resize-detector": "^8.0.4", + "react-smooth": "^2.0.2", + "recharts-scale": "^0.4.4", + "reduce-css-calc": "^2.1.8", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -5964,6 +6319,27 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/victory-vendor": { + "version": "36.6.8", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.8.tgz", + "integrity": "sha512-H3kyQ+2zgjMPvbPqAl7Vwm2FD5dU7/4bCTQakFQnpIsfDljeOMDojRsrmJfwh4oAlNnWhpAf+mbAoLh8u7dwyQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -7262,6 +7638,12 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, "@next/env": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.2.4.tgz", @@ -7598,6 +7980,60 @@ "tslib": "^2.4.0" } }, + "@types/d3-array": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.4.tgz", + "integrity": "sha512-nwvEkG9vYOc0Ic7G7kwgviY4AQlTfYGIZ0fqB7CQHXGyYM6nO7kJh5EguSNA3jfh4rq7Sb7eMVq8isuvg2/miQ==" + }, + "@types/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" + }, + "@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "requires": { + "@types/d3-color": "*" + } + }, + "@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "@types/d3-scale": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", + "requires": { + "@types/d3-time": "*" + } + }, + "@types/d3-shape": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", + "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", + "requires": { + "@types/d3-path": "*" + } + }, + "@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" + }, + "@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -7985,6 +8421,15 @@ "supports-color": "^7.1.0" } }, + "chart.js": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.1.tgz", + "integrity": "sha512-6YbpQ0nt3NovAgOzbkSSeeAQu/3za1319dPUQTXn9WcOpywM8rGKxJHrhS8V8xEkAlk8YhEfjbuAPfUyp6jIsw==", + "peer": true, + "requires": { + "@kurkle/color": "^0.3.0" + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -7994,6 +8439,11 @@ "safe-buffer": "^5.0.1" } }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -8097,11 +8547,93 @@ "tiny-invariant": "^1.0.6" } }, + "css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, "csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "requires": { + "internmap": "1 - 2" + } + }, + "d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, + "d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" + }, + "d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "requires": { + "d3-color": "1 - 3" + } + }, + "d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" + }, + "d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "requires": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + } + }, + "d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "requires": { + "d3-path": "^3.1.0" + } + }, + "d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "requires": { + "d3-array": "2 - 3" + } + }, + "d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "requires": { + "d3-time": "1 - 3" + } + }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -8115,6 +8647,11 @@ "ms": "2.1.2" } }, + "decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "deep-equal": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz", @@ -8189,6 +8726,14 @@ "esutils": "^2.0.2" } }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -8614,11 +9159,21 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-equals": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", + "integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==" + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -9022,6 +9577,11 @@ "side-channel": "^1.0.4" } }, + "internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -9326,6 +9886,11 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -9696,6 +10261,11 @@ "source-map-js": "^1.0.2" } }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, "preact": { "version": "10.13.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.1.tgz", @@ -9744,6 +10314,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, + "qr.js": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", + "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9766,6 +10341,12 @@ "prop-types": "^15.6.2" } }, + "react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "requires": {} + }, "react-clientside-effect": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", @@ -9806,6 +10387,20 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-qr-code": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.11.tgz", + "integrity": "sha512-P7mvVM5vk9NjGdHMt4Z0KWeeJYwRAtonHTghZT2r+AASinLUUKQ9wfsGH2lPKsT++gps7hXmaiMGRvwTDEL9OA==", + "requires": { + "prop-types": "^15.8.1", + "qr.js": "0.0.0" + } + }, "react-redux": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", @@ -9847,6 +10442,23 @@ "tslib": "^2.0.0" } }, + "react-resize-detector": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.0.4.tgz", + "integrity": "sha512-ln9pMAob8y8mc9UI4aZuuWFiyMqBjnTs/sxe9Vs9dPXUjwCTeKK1FP8I75ufnb/2mEEZXG6wOo/fjMcBRRuAXw==", + "requires": { + "lodash": "^4.17.21" + } + }, + "react-smooth": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.2.tgz", + "integrity": "sha512-pgqSp1q8rAGtF1bXQE0m3CHGLNfZZh5oA5o1tsPLXRHnKtkujMIJ8Ws5nO1mTySZf1c4vgwlEk+pHi3Ln6eYLw==", + "requires": { + "fast-equals": "^4.0.3", + "react-transition-group": "2.9.0" + } + }, "react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -9857,6 +10469,17 @@ "tslib": "^2.0.0" } }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -9867,6 +10490,39 @@ "util-deprecate": "^1.0.1" } }, + "recharts": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.5.0.tgz", + "integrity": "sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ==", + "requires": { + "classnames": "^2.2.5", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-resize-detector": "^8.0.4", + "react-smooth": "^2.0.2", + "recharts-scale": "^0.4.4", + "reduce-css-calc": "^2.1.8", + "victory-vendor": "^36.6.8" + } + }, + "recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "requires": { + "decimal.js-light": "^2.4.1" + } + }, + "reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, "redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -10318,6 +10974,27 @@ "safe-buffer": "^5.1.1" } }, + "victory-vendor": { + "version": "36.6.8", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.8.tgz", + "integrity": "sha512-H3kyQ+2zgjMPvbPqAl7Vwm2FD5dU7/4bCTQakFQnpIsfDljeOMDojRsrmJfwh4oAlNnWhpAf+mbAoLh8u7dwyQ==", + "requires": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 2c8324f..cbf6c2b 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,11 @@ "nostr-tools": "^1.7.4", "react": "18.2.0", "react-calendar-heatmap": "^1.9.0", + "react-chartjs-2": "^5.2.0", "react-dom": "18.2.0", + "react-qr-code": "^2.0.11", "react-redux": "^8.0.5", + "recharts": "^2.5.0", "redux-thunk": "^2.4.2" } } diff --git a/src/components/QR/QR.js b/src/components/QR/QR.js new file mode 100644 index 0000000..68a05b3 --- /dev/null +++ b/src/components/QR/QR.js @@ -0,0 +1,32 @@ +import { useState } from "react"; +import QRCode from "react-qr-code"; +import styles from "./qr.module.css"; + +const QR = ({ value }) => { + return ( + // Can be anything instead of `maxWidth` that limits the width. +
+ +
+ ); +}; + +export default QR; diff --git a/src/components/QR/qr.module.css b/src/components/QR/qr.module.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Recent/Recent.js b/src/components/Recent/Recent.js index 7e8768a..cac03c6 100644 --- a/src/components/Recent/Recent.js +++ b/src/components/Recent/Recent.js @@ -1,30 +1,51 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect } from "react"; +import { useSession } from "next-auth/react"; +import styles from "./recent.module.css"; const Recent = () => { - const [data, setData] = useState(null); - const username = 'AustinKelsay'; -// const access_token = 'your_access_token_here'; - const url = `https://api.github.com/users/${username}/events`; + const [events, setEvents] = useState([]); + const { data: session, status } = useSession(); useEffect(() => { - fetch(url - ) - .then((response) => response.json()) - .then((data) => setData(data), - console.log(setData)) - .catch((error) => console.error(error)); - }, [url]); + const fetchEvents = async () => { + try { + const response = await fetch( + "https://api.github.com/users/AustinKelsay/events", + { + headers: { + Authorization: `token ${session.token.accessToken}`, + }, + } + ); + const data = await response.json(); + setEvents(data); + } catch (error) { + console.error("Failed to fetch events:", error); + } + }; - if (!data) { - return
Loading...
; - } + if (status === "authenticated") { + fetchEvents(); + } + }, [status]); - if (data.message) { - return
Error: {data.message}
; - } - - // do something with the data - return
{JSON.stringify(data)}
; + return ( +
+

Recent GitHub Activity

+
+
+ {events.map((event) => ( +
+
{event.type}
+
+ {JSON.stringify(event.payload)} +
+
+ ))} +
+
+
+ ); }; export default Recent; diff --git a/src/components/Recent/recent.module.css b/src/components/Recent/recent.module.css new file mode 100644 index 0000000..5dae48f --- /dev/null +++ b/src/components/Recent/recent.module.css @@ -0,0 +1,44 @@ +.container { + max-width: 800px; + max-height: 100vh; + margin: 0 auto; + color: #fff; + background-color: #111; + padding: 50px; + border-radius: 10px; +} + +.header { + margin-bottom: 20px; + font-size: 24px; + font-weight: bold; +} + +.eventList { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; +} + +.eventListContainer { + max-height: 100vh; +} + +.event { + background-color: #222; + padding: 20px; + border-radius: 5px; + box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.5); +} + +.eventType { + font-weight: bold; + margin-bottom: 10px; + color: #8affd4; +} + +.eventPayload { + font-family: monospace; + white-space: pre-wrap; + color: #ccc; +} diff --git a/src/components/activeRepos/ActiveRepos.js b/src/components/activeRepos/ActiveRepos.js new file mode 100644 index 0000000..5835e3e --- /dev/null +++ b/src/components/activeRepos/ActiveRepos.js @@ -0,0 +1,87 @@ +import { useState, useEffect } from "react"; +import { Button } from "@chakra-ui/react"; +import { createRepoEvent } from "@/utils/createRepoEvent"; +import styles from "./repos.module.css"; + +const ActiveRepos = () => { + const [repos, setRepos] = useState([]); + + useEffect(() => { + const fetchRepos = async () => { + const response = await fetch( + "https://api.github.com/users/austinkelsay/repos?sort=pushed&per_page=6" + ); + const data = await response.json(); + console.log(data); + setRepos(data); + }; + fetchRepos(); + }, []); + + const handleBroadcast = async ({ repository }) => { + console.log("repository in handleBroadcast", repository); + const owner = repository.owner.login; + const repoName = repository.name; + const url = repository.html_url; + + const repo = { + owner, + name: repoName, + url, + }; + + const pubkey = await window.nostr.getPublicKey(); + + if (!pubkey) { + return; + } + + const event = createRepoEvent({ pubkey, repo }); + + console.log("event in handleBroadcast", event); + }; + + return ( +
+

Recent Repositories

+
+
+ {repos.length && + repos.map((repo) => ( + +
{repo.name}
+
{repo.description}
+
+ {repo.language} + + {repo.stargazers_count} stars + + + Updated on {new Date(repo.pushed_at).toLocaleDateString()} + +
+
+ +
+
+ ))} +
+
+
+ ); +}; + +export default ActiveRepos; diff --git a/src/components/activeRepos/repos.module.css b/src/components/activeRepos/repos.module.css new file mode 100644 index 0000000..b184fab --- /dev/null +++ b/src/components/activeRepos/repos.module.css @@ -0,0 +1,83 @@ +.container { + max-width: 800px; + max-height: 100vh; + margin: 0 auto; + color: #fff; + background-color: #111; + padding: 50px; + border-radius: 10px; +} + +.header { + margin-bottom: 20px; + font-size: 24px; + font-weight: bold; +} + +.eventList { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; +} + +.eventListContainer { + max-height: 100vh; +} + +.event { + background-color: #222; + padding: 20px; + border-radius: 5px; + box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.5); + transition: all 0.3s ease-in-out; +} + +.event:hover { + transform: translateY(-5px); + box-shadow: 0px 0px 20px 2px rgba(0, 0, 0, 0.5); +} + +.eventType { + font-weight: bold; + margin-bottom: 10px; + color: #8affd4; +} + +.eventPayload { + font-family: monospace; + white-space: pre-wrap; + color: #ccc; + margin-bottom: 10px; +} + +.details { + display: flex; + justify-content: space-between; + font-size: 0.8rem; + color: #ccc; +} + +.details > * { + margin: 0.25rem 0; +} + +.language { + font-weight: bold; + text-transform: uppercase; +} + +.stars { + cursor: pointer; + text-decoration: none; + color: #8affd4; +} + +.stars:hover { + text-decoration: underline; +} + +.buttonContainer { + display: flex; + flex-direction: row; + justify-content: flex-end; +} diff --git a/src/components/chat/ChatInput.js b/src/components/chat/ChatInput.js new file mode 100644 index 0000000..8a1067c --- /dev/null +++ b/src/components/chat/ChatInput.js @@ -0,0 +1,73 @@ +import React, { useState } from "react"; +import { Button } from "@chakra-ui/react"; +import { + generatePrivateKey, + getPublicKey, + signEvent, + getEventHash, + validateEvent, + relayInit, +} from "nostr-tools"; +import styles from "./chat.module.css"; + +const ChatInput = () => { + const [content, setContent] = useState(""); + + const handleChange = (event) => { + setContent(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + + const privateKey = await generatePrivateKey(); + const publicKey = await getPublicKey(privateKey); + + const eventObject = { + kind: 1, + pubkey: publicKey, + created_at: Math.floor(Date.now() / 1000), + tags: [["#devstr"]], + content, + }; + + eventObject.id = getEventHash(eventObject); + eventObject.sig = signEvent(eventObject, privateKey); + + const relay = relayInit("ws://72.177.66.131:4848"); + + await relay.connect(); + + try { + console.log("eventObject", eventObject); + await relay.publish(eventObject); + console.log("Event published successfully"); + } catch (err) { + console.error(`Failed to publish event: ${err}`); + } + + setContent(""); + }; + + return ( +
+
+ + +
+
+ ); +}; + +export default ChatInput; diff --git a/src/components/chat/ChatList.js b/src/components/chat/ChatList.js new file mode 100644 index 0000000..e30d1d3 --- /dev/null +++ b/src/components/chat/ChatList.js @@ -0,0 +1,93 @@ +import React, { useState, useEffect } from "react"; +import { relayInit } from "nostr-tools"; +import styles from "./chat.module.css"; + +const ChatList = () => { + const [events, setEvents] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [eventsPerPage, setEventsPerPage] = useState(10); + + useEffect(() => { + const relay = relayInit("ws://72.177.66.131:4848"); + relay.connect(); + + // Filter for any events with the #devstr tag + const sub = relay.sub([ + { + kinds: [1], + // tags: [["#devstr"]], + }, + ]); + + sub.on("event", (event) => { + setEvents((prevState) => [...prevState, event]); + }); + + return () => { + sub.unsub(); + relay.close(); + }; + }, []); + + const indexOfLastEvent = currentPage * eventsPerPage; + const indexOfFirstEvent = indexOfLastEvent - eventsPerPage; + const currentEvents = events.slice(indexOfFirstEvent, indexOfLastEvent); + + const totalPages = Math.ceil(events.length / eventsPerPage); + + const pageNumbers = []; + if (currentPage <= 5) { + for (let i = 1; i <= Math.min(totalPages, 9); i++) { + pageNumbers.push(i); + } + } else { + pageNumbers.push(1, "..."); + for ( + let i = currentPage - 3; + i <= Math.min(currentPage + 3, totalPages); + i++ + ) { + pageNumbers.push(i); + } + if (currentPage + 3 < totalPages) { + pageNumbers.push("...", totalPages); + } else if (currentPage + 2 === totalPages) { + pageNumbers.push(totalPages - 1, totalPages); + } else if (currentPage + 1 === totalPages) { + pageNumbers.push(totalPages); + } + } + + const handleClick = (event) => { + const pageNumber = Number(event.target.id); + if (!isNaN(pageNumber)) { + setCurrentPage(pageNumber); + } + }; + + return ( +
+ + +
+ ); +}; + +export default ChatList; diff --git a/src/components/chat/chat.module.css b/src/components/chat/chat.module.css index c7723de..019a981 100644 --- a/src/components/chat/chat.module.css +++ b/src/components/chat/chat.module.css @@ -1,30 +1,30 @@ .chatInterface { - background-color: slategray; - height: 90vh; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .messageList { - display: flex; - flex-direction: column; - padding: 16px; - overflow-y: scroll; - } - - .message { - margin: 8px; - max-width: 80%; - border-radius: 12px; - padding: 8px 12px; - font-size: 16px; - line-height: 24px; - background-color: #9461e3; - align-self: flex-end; - } - - /* .message.sent { + background-color: slategray; + height: auto; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.messageList { + display: flex; + flex-direction: column; + padding: 16px; + overflow-y: scroll; +} + +.message { + margin: 8px; + max-width: 80%; + border-radius: 12px; + padding: 8px 12px; + font-size: 16px; + line-height: 24px; + background-color: #9461e3; + align-self: flex-end; +} + +/* .message.sent { background-color: #007aff; color: white; align-self: flex-end; @@ -35,47 +35,104 @@ color: black; align-self: flex-start; } */ - - .form { - display: flex; - align-items: center; - padding: 16px; - } - - .input{ - flex: 1; - border-radius: 24px; - border: none; - padding: 12px; - margin-right: 8px; - font-size: 16px; - line-height: 24px; - } - - .submitBtn{ - background-color: #9461e3; - color: black; - border-radius: 50%; - border: none; - width: 48px; - height: 48px; - font-size: 16px; - font-weight: bold; - line-height: 24px; + +.form { + display: flex; + align-items: center; + padding: 16px; +} + +.input { + flex: 1; + border-radius: 24px; + border: none; + padding: 12px; + margin-right: 8px; + font-size: 16px; + line-height: 24px; +} + +.submitBtn { + background-color: #9461e3; + color: black; + border-radius: 50%; + border: none; + width: 48px; + height: 48px; + font-size: 16px; + font-weight: bold; + line-height: 24px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} + +@media screen and (max-width: 500px) { + .chatInterface { + background-color: slategray; + height: 95vh; display: flex; - justify-content: center; - align-items: center; - cursor: pointer; + flex-direction: column; + justify-content: space-between; } - - @media screen and (max-width: 500px) { - - .chatInterface { - background-color: slategray; - height: 95vh; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - } \ No newline at end of file +} + +.nostrChat { + display: flex; + flex-direction: column; + align-items: center; +} + +.nostrInput { + margin-bottom: 10px; + padding: 10px; + border-radius: 5px; + border: 1px solid #ccc; +} + +.nostrChatButton { + padding: 10px; + background-color: #0077ff; + color: #fff; + border: none; + border-radius: 5px; + cursor: pointer; +} + +.chatList { + max-width: 95%; + height: auto; + margin: 0 auto; + padding: 1rem; + border: 1px solid #ccc; +} + +.currentEvents { + list-style: none; + padding: 1%; +} + +.pageNumbers { + display: flex; + justify-content: center; + margin-top: 1rem; + padding: 0; + list-style: none; +} + +.pageNumbers li { + margin: 0 0.5rem; + cursor: pointer; + font-size: 1.2rem; +} + +.pageNumbers li.active { + text-decoration: underline; +} + +.event { + padding-top: 1%; + padding-bottom: 1%; + border-bottom: 1px solid #ccc; +} diff --git a/src/components/contributionCalendar/ContributionCalendar.js b/src/components/contributionCalendar/ContributionCalendar.js index b8a34f3..c1f6f40 100644 --- a/src/components/contributionCalendar/ContributionCalendar.js +++ b/src/components/contributionCalendar/ContributionCalendar.js @@ -107,9 +107,9 @@ const ContributionCalendar = () => { return "color-empty"; } if (value.count > 8) { - return "colorScale8" + return "colorScale8"; } else { - return `colorScale${value.count}` + return `colorScale${value.count}`; } }} onMouseOver={(event, value) => { @@ -125,4 +125,4 @@ const ContributionCalendar = () => { ); }; -export default ContributionCalendar; \ No newline at end of file +export default ContributionCalendar; diff --git a/src/components/languagesUsed/LanguagesUsed.js b/src/components/languagesUsed/LanguagesUsed.js index e4d89c9..a16320f 100644 --- a/src/components/languagesUsed/LanguagesUsed.js +++ b/src/components/languagesUsed/LanguagesUsed.js @@ -1,20 +1,23 @@ -import styles from "./languages.module.css" -import { useState, useEffect } from 'react'; +import styles from "./languages.module.css"; +import { useState, useEffect } from "react"; +import { PieChart, Pie, Cell, ResponsiveContainer } from "recharts"; function LanguagesUsed() { const [languages, setLanguages] = useState([]); useEffect(() => { - const username = 'AustinKelsay'; // Replace with the GitHub username you want to fetch + const username = "AustinKelsay"; // Replace with the GitHub username you want to fetch const url = `https://api.github.com/users/${username}/repos`; fetch(url) - .then(response => response.json()) - .then(data => { + .then((response) => response.json()) + .then((data) => { // Extract the language used in each repository and count their frequency - const languages = data.map(repo => repo.language); + const languages = data.map((repo) => repo.language); const languageCount = languages.reduce((acc, language) => { - acc[language] = (acc[language] || 0) + 1; + if (language) { + acc[language] = (acc[language] || 0) + 1; + } return acc; }, {}); @@ -26,24 +29,41 @@ function LanguagesUsed() { setLanguages(topLanguages); }) - .catch(error => console.error(error)); + .catch((error) => console.error(error)); }, []); return ( -
+

Most Used Programming Languages

- +
+ + + + `${language}: ${(percent * 100).toFixed(0)}%` + } + outerRadius={80} + fill="#8884d8" + dataKey="count" + > + {languages.map((entry, index) => ( + + ))} + + + +
); } +const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"]; - - -export default LanguagesUsed; \ No newline at end of file +export default LanguagesUsed; diff --git a/src/components/languagesUsed/languages.module.css b/src/components/languagesUsed/languages.module.css index 715eab6..3140d9f 100644 --- a/src/components/languagesUsed/languages.module.css +++ b/src/components/languagesUsed/languages.module.css @@ -1,6 +1,4 @@ .container { - - margin-top: 20px; - font-size: 20px; - -} \ No newline at end of file + margin-top: 20px; + font-size: 20px; +} diff --git a/src/components/navbar/navbar.js b/src/components/navbar/navbar.js index 831552c..9d3870c 100644 --- a/src/components/navbar/navbar.js +++ b/src/components/navbar/navbar.js @@ -1,48 +1,109 @@ import { + Card, + Heading, Drawer, DrawerBody, DrawerHeader, DrawerOverlay, DrawerContent, Button, - IconButton + Text, + IconButton, } from "@chakra-ui/react"; -import { useDisclosure } from '@chakra-ui/react' +import { useDisclosure } from "@chakra-ui/react"; +import Image from "next/image"; import styles from "./styles.module.css"; -import Link from 'next/link' -import Login from "../Onboarding/GithubLogin" - +import Link from "next/link"; +import Login from "../Onboarding/GithubLogin"; +import { useRouter } from "next/router"; +import { useSession } from "next-auth/react"; const Navbar = () => { - const { isOpen, onOpen, onClose } = useDisclosure() + const { isOpen, onOpen, onClose } = useDisclosure(); + const { data: session, status } = useSession(); + const router = useRouter(); + const handleProfileClick = () => { + router.push("/profile"); + }; return ( -
- - - - - - +
+ + + + + + + + - Menu + Menu -

Home

-

Profile

-

Chat

+

+ Home +

+

+ Profile +

+

+ Chat +

- -
- - ) -} + + Devstr + +
+ {status === "authenticated" && ( + + profile-banner + + {session.session.user.name.replace(/\s/g, "")} + + + )} + +
+
+ ); +}; -export default Navbar; \ No newline at end of file +export default Navbar; diff --git a/src/components/navbar/styles.module.css b/src/components/navbar/styles.module.css index 58ba749..f520288 100644 --- a/src/components/navbar/styles.module.css +++ b/src/components/navbar/styles.module.css @@ -1,12 +1,31 @@ .navbar { - padding: 2%; - background-color: rgb(33, 33, 33); + padding: 1%; + padding-left: 2%; + padding-right: 2%; + background-color: #212121; + color: white; width: 100%; display: flex; flex-direction: row; justify-content: space-between; } -.icon{ - padding:4px; -} \ No newline at end of file +.navbarRight { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 1rem; +} + +.title { + font-size: 1.5rem; + font-weight: bold; + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.icon { + padding: 4px; +} diff --git a/src/pages/chat.js b/src/pages/chat.js index f9d0ae5..60f285b 100644 --- a/src/pages/chat.js +++ b/src/pages/chat.js @@ -1,13 +1,14 @@ -import ChatLayout from "../components/chat/ChatLayout" +import ChatInput from "@/components/chat/ChatInput"; +import ChatList from "@/components/chat/ChatList"; const Chat = () => { - - return ( - <> - - - - ) -} - -export default Chat; \ No newline at end of file + return ( + <> + {/* */} + + {/* */} + + ); +}; + +export default Chat; diff --git a/src/pages/index.js b/src/pages/index.js index 1ae5226..2835f13 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,6 +1,6 @@ import Head from "next/head"; import Image from "next/image"; -import hero from "../pages/devstr.png" +import hero from "../pages/devstr.png"; import styles from "@/styles/Home.module.css"; export default function Home() { @@ -14,20 +14,18 @@ export default function Home() {
- + hero
-
+
); } - // import Image from "next/image" // import styles from "../styles/Home.module.css" // export default function Home() { - // return ( //
//
@@ -35,4 +33,4 @@ export default function Home() { //
//
// ) -// } \ No newline at end of file +// } diff --git a/src/pages/profile.js b/src/pages/profile.js index f3a0c6a..2456498 100644 --- a/src/pages/profile.js +++ b/src/pages/profile.js @@ -1,65 +1,82 @@ +import { useState, useEffect } from "react"; import { Avatar, Text, Flex, Box } from "@chakra-ui/react"; -import ContributionCalendar from "../components/contributionCalendar/ContributionCalendar" -// import PinnedRepos from "../src/components/pinnedRepos/PinnedRepos"; +import ContributionCalendar from "../components/contributionCalendar/ContributionCalendar"; +import ActiveRepos from "../components/activeRepos/ActiveRepos"; import LanguagesUsed from "../components/languagesUsed/LanguagesUsed"; -// import QR from "../src/components/QR/QR" -import Recent from "../components/Recent/Recent" -import styles from "../styles/profile.module.css" -import {useState} from "react" +import QR from "../components/QR/QR"; +import Recent from "../components/Recent/Recent"; +import { useSession } from "next-auth/react"; +import styles from "../styles/profile.module.css"; const Profile = () => { + const [bio, setBio] = useState(""); + const [username, setUsername] = useState(""); + const [avatarUrl, setAvatarUrl] = useState(""); - const [bio, setBio] = useState('bio'); + const { data: session, status } = useSession(); - function addBio() { - const bioContent = prompt('add your bio: '); - setBio(bioContent); + useEffect(() => { + async function fetchGitHubData() { + const response = await fetch( + `https://api.github.com/users/${session.session.user.name.replace( + " ", + "" + )}` + ); + const data = await response.json(); + setUsername(data.login); + setBio(data.bio); + setAvatarUrl(data.avatar_url); } - let loggedIn = true - return ( - <> - {loggedIn? ( -
-
-
-
- - - username - date joined - {bio} - - -
-
- -
- - {/* */} - - - - + if (status === "authenticated") { + fetchGitHubData(); + } + }, [status, session]); + + let loggedIn = true; + + return ( + <> + {loggedIn ? ( +
+
+
+
+ + + + {username} + + {bio} +
-
-
- {/* */} -
-
- -
+
+
-
- ): - - ( -
-

Log in to view profile

+ + + + + + +
+
+
+ {" "} +
+
+
- )} - - ) -} +
+
+ ) : ( +
+

Log in to view profile

+
+ )} + + ); +}; -export default Profile; \ No newline at end of file +export default Profile; diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css index 3492447..922b7e4 100644 --- a/src/styles/Home.module.css +++ b/src/styles/Home.module.css @@ -5,10 +5,9 @@ align-items: center; padding: 6rem; min-height: 100vh; - } -.image{ +.image { height: 600px; width: 600px; } @@ -103,7 +102,7 @@ .center::before, .center::after { - content: ''; + content: ""; left: 50%; position: absolute; filter: blur(45px); @@ -131,7 +130,7 @@ .thirteen::before, .thirteen::after { - content: ''; + content: ""; position: absolute; z-index: -1; } diff --git a/src/styles/profile.module.css b/src/styles/profile.module.css index 4e75e57..16b65f4 100644 --- a/src/styles/profile.module.css +++ b/src/styles/profile.module.css @@ -1,75 +1,72 @@ -.row{ - display: flex; - justify-content:space-between; - color: white; - background-color: black; - +.row { + display: flex; + justify-content: space-between; + color: white; + background-color: black; } -.main{ - padding:10px; - display: flex; - flex-direction: column; - width:70vh; +.main { + padding: 10px; + display: flex; + flex-direction: column; + width: 70vh; } -.profileCard{ - display:flex; - margin:10px; +.profileCard { + display: flex; + margin: 10px; } -.aside{ - border-left: 1px solid lightgray; +.aside { + border-left: 1px solid lightgray; } -.qr, .recent{ - padding:10px; - height:50vh; - width: 20vw; +.qr, +.recent { + padding: 10px; + height: 50vh; + width: 25vw; } -.menu{ - padding:10px; - height:50vh; - width: 10vw; +.menu { + padding: 10px; + height: 50vh; + width: 10vw; } -.qr{ - display:flex; - flex-direction: row; - justify-content: center; - align-items: center; +.qr { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; } -.error{ - height: 100vh; +.error { + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +@media screen and (max-width: 500px) { + .main { + padding: 5px; + width: 100vw; + } + .contribution { + width: 100vw; + padding: 10px; + } + .row { + display: block; + } + .menu { + display: none; + } + .aside { + border-left: none; + } + .qr { display: flex; - flex-direction: column; + flex-direction: row; justify-content: center; align-items: center; + width: 100vw; + } } - -@media screen and (max-width: 500px){ - .main{ - padding:5px; - width:100vw; - } - .contribution{ - width:100vw; - padding:10px; - - } - .row{ - display:block; - - } - .menu{ - display:none; - } - .aside{ - border-left: none; - } - .qr{ - display:flex; - flex-direction: row; - justify-content: center; - align-items: center; - width:100vw; - } - -} \ No newline at end of file diff --git a/src/utils/createChatEvent.js b/src/utils/createChatEvent.js new file mode 100644 index 0000000..357644e --- /dev/null +++ b/src/utils/createChatEvent.js @@ -0,0 +1,60 @@ +import React, { useState } from "react"; +import { + generatePrivateKey, + getPublicKey, + signEvent, + getEventHash, + validateEvent, + relayInit, +} from "nostr-tools"; + +const NostrChat = () => { + const [content, setContent] = useState(""); + + const handleChange = (event) => { + setContent(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + + const privateKey = await generatePrivateKey(); + const publicKey = await getPublicKey(privateKey); + + const eventObject = { + kind: 1, + pubkey: publicKey, + created_at: Math.floor(Date.now() / 1000), + tags: [], + content, + }; + + eventObject.id = getEventHash(eventObject); + eventObject.sig = signEvent(eventObject, privateKey); + + const relay = relayInit("wss://relay.plebstr.com"); + + await relay.connect(); + + try { + await relay.publish(eventObject); + console.log("Event published successfully"); + } catch (err) { + console.error(`Failed to publish event: ${err}`); + } + + setContent(""); + }; + + return ( +
+ + +
+ ); +}; + +export default NostrChat; diff --git a/src/utils/createRepoEvent.js b/src/utils/createRepoEvent.js new file mode 100644 index 0000000..53c5408 --- /dev/null +++ b/src/utils/createRepoEvent.js @@ -0,0 +1,43 @@ +import React, { useState } from "react"; +import { + generatePrivateKey, + getPublicKey, + signEvent, + getEventHash, + validateEvent, + relayInit, +} from "nostr-tools"; + +export const createRepoEvent = async ({ pubkey, repo }) => { + const eventObject = { + kind: 1, + pubkey: pubkey, + created_at: Math.floor(Date.now() / 1000), + tags: [["#devstr"]], + // stringify content + + content: JSON.stringify({ + repo: repo, + type: "repo", + }), + }; + + console.log("eventObject", eventObject); + + eventObject.id = getEventHash(eventObject); + const signedEvent = await window.nostr.signEvent(eventObject); + + eventObject.sig = signedEvent.sig; + + const relay = relayInit("wss://relay.plebstr.com"); + + await relay.connect(); + + try { + console.log("eventObject", eventObject); + await relay.publish(eventObject); + console.log("Event published successfully"); + } catch (err) { + console.error(`Failed to publish event: ${err}`); + } +}; diff --git a/src/utils/readChatEvents.js b/src/utils/readChatEvents.js new file mode 100644 index 0000000..a526f95 --- /dev/null +++ b/src/utils/readChatEvents.js @@ -0,0 +1,35 @@ +import React, { useState, useEffect } from "react"; +import { relayInit } from "nostr-tools"; + +const ReadChatEvents = () => { + const [events, setEvents] = useState([]); + + useEffect(() => { + const relay = relayInit("wss://relay.snort.social"); + relay.connect(); + + const sub = relay.sub([{ kinds: [1] }]); + + sub.on("event", (event) => { + setEvents((prevState) => [...prevState, event]); + }); + + return () => { + sub.unsub(); + relay.close(); + }; + }, []); + + return ( +
+

Kind 1 Events:

+
    + {events.map((event) => ( +
  • {event.content}
  • + ))} +
+
+ ); +}; + +export default ReadChatEvents;