diff --git a/infra/database.js b/infra/database.js index fd55d03b4..81f350d02 100644 --- a/infra/database.js +++ b/infra/database.js @@ -11,7 +11,7 @@ const configurations = { database: process.env.POSTGRES_DB, password: process.env.POSTGRES_PASSWORD, port: process.env.POSTGRES_PORT, - connectionTimeoutMillis: 1000, + connectionTimeoutMillis: 2000, idleTimeoutMillis: 30000, max: 1, ssl: { diff --git a/jsconfig.json b/jsconfig.json index 36aa1a4dc..3ba6eb299 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,5 +1,8 @@ { "compilerOptions": { - "baseUrl": "." + "baseUrl": ".", + "paths": { + "@/*": ["pages/interface/components/*"] + } } } diff --git a/models/rss.js b/models/rss.js index 51cb6c148..cf12d8027 100644 --- a/models/rss.js +++ b/models/rss.js @@ -1,6 +1,6 @@ -import { renderToStaticMarkup } from 'react-dom/server'; -import { Viewer } from 'pages/interface'; +import { Viewer } from '@/TabNewsUI'; import removeMarkdown from 'models/remove-markdown'; +import { renderToStaticMarkup } from 'react-dom/server'; import { Feed } from 'feed'; import webserver from 'infra/webserver.js'; diff --git a/package-lock.json b/package-lock.json index f162d884d..364222ac3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,9 +28,6 @@ "cross-fetch": "3.1.5", "date-fns": "2.29.3", "feed": "4.2.2", - "github-markdown-css": "5.2.0", - "highlight.js": "11.7.0", - "ip-anonymize": "0.1.0", "is-in-subnet": "4.0.1", "joi": "17.8.3", "next": "13.2.4", @@ -3125,7 +3122,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3500,6 +3497,16 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3525,7 +3532,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "devOptional": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -3781,6 +3788,47 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "optional": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -6236,7 +6284,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, + "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6369,7 +6417,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -6528,14 +6575,6 @@ "node": ">=10" } }, - "node_modules/github-markdown-css": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.2.0.tgz", - "integrity": "sha512-hq5RaCInSUZ48bImOZpkppW2/MT44StRgsbsZ8YA4vJFwLKB/Vo3k7R2t+pUGqO+ThG0QDMi96TewV/B3vyItg==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7109,6 +7148,13 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "optional": true, + "peer": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -7241,11 +7287,6 @@ "node": ">=12" } }, - "node_modules/ip-anonymize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ip-anonymize/-/ip-anonymize-0.1.0.tgz", - "integrity": "sha512-cZJu+N5JKKFGMK0eEQWNaQMn2EhCysciVM6eotCJwfqotj16BTfVchKsJCH6mQAT9N0GC7oWRcsZ6Lb8dDiwTA==" - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -7294,6 +7335,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "optional": true, + "peer": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -7390,7 +7444,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7420,7 +7474,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -7470,7 +7524,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.12.0" } @@ -10330,7 +10384,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -11495,6 +11549,19 @@ "node": ">= 6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "optional": true, + "peer": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -12022,6 +12089,24 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sass": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", + "optional": true, + "peer": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -12763,7 +12848,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -15885,7 +15970,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, + "devOptional": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -16154,6 +16239,13 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "optional": true, + "peer": true + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -16179,7 +16271,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "devOptional": true, "requires": { "fill-range": "^7.0.1" } @@ -16343,6 +16435,35 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "optional": true, + "peer": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "optional": true, + "peer": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -18191,7 +18312,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, + "devOptional": true, "requires": { "to-regex-range": "^5.0.1" } @@ -18296,7 +18417,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { @@ -18402,11 +18522,6 @@ "through2": "^4.0.0" } }, - "github-markdown-css": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.2.0.tgz", - "integrity": "sha512-hq5RaCInSUZ48bImOZpkppW2/MT44StRgsbsZ8YA4vJFwLKB/Vo3k7R2t+pUGqO+ThG0QDMi96TewV/B3vyItg==" - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -18823,6 +18938,13 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "optional": true, + "peer": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -18924,11 +19046,6 @@ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" }, - "ip-anonymize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ip-anonymize/-/ip-anonymize-0.1.0.tgz", - "integrity": "sha512-cZJu+N5JKKFGMK0eEQWNaQMn2EhCysciVM6eotCJwfqotj16BTfVchKsJCH6mQAT9N0GC7oWRcsZ6Lb8dDiwTA==" - }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -18965,6 +19082,16 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "optional": true, + "peer": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -19014,7 +19141,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true + "devOptional": true }, "is-fullwidth-code-point": { "version": "4.0.0", @@ -19032,7 +19159,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "requires": { "is-extglob": "^2.1.1" } @@ -19064,7 +19191,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "devOptional": true }, "is-number-object": { "version": "1.0.7", @@ -21068,7 +21195,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "devOptional": true }, "normalize-range": { "version": "0.1.2", @@ -21891,6 +22018,16 @@ "util-deprecate": "^1.0.1" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "optional": true, + "peer": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -22264,6 +22401,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sass": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", + "optional": true, + "peer": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -22842,7 +22991,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "requires": { "is-number": "^7.0.0" } diff --git a/package.json b/package.json index 5a9583faf..9d53d9c83 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,6 @@ "cross-fetch": "3.1.5", "date-fns": "2.29.3", "feed": "4.2.2", - "github-markdown-css": "5.2.0", - "highlight.js": "11.7.0", - "ip-anonymize": "0.1.0", "is-in-subnet": "4.0.1", "joi": "17.8.3", "next": "13.2.4", diff --git a/pages/404.public.js b/pages/404.public.js index d8e99729c..49632b2f3 100644 --- a/pages/404.public.js +++ b/pages/404.public.js @@ -1,6 +1,5 @@ +import { Box, DefaultLayout, Link } from '@/TabNewsUI'; import Image from 'next/image'; -import { DefaultLayout } from 'pages/interface/index.js'; -import { Box, Link } from '@primer/react'; import botSleepyFaceDarkTransparent from 'public/brand/bot-sleepy-face-dark-transparent.svg'; export default function Custom404() { diff --git a/pages/500.public.js b/pages/500.public.js index 241759ed4..92ace58f1 100644 --- a/pages/500.public.js +++ b/pages/500.public.js @@ -1,6 +1,5 @@ +import { Box, DefaultLayout, Link } from '@/TabNewsUI'; import Image from 'next/image'; -import { DefaultLayout } from 'pages/interface/index.js'; -import { Box, Link } from '@primer/react'; import botDeadFaceDarkTransparent from 'public/brand/bot-dead-face-dark-transparent.svg'; export default function Custom500() { diff --git a/pages/[username]/[slug]/index.public.js b/pages/[username]/[slug]/index.public.js index 145922584..91b449063 100644 --- a/pages/[username]/[slug]/index.public.js +++ b/pages/[username]/[slug]/index.public.js @@ -1,15 +1,15 @@ -import useSWR from 'swr'; -import { useEffect, useState } from 'react'; -import { Link, DefaultLayout, Content, TabCoinButtons, Confetti, useCollapse } from 'pages/interface/index.js'; -import user from 'models/user.js'; -import content from 'models/content.js'; -import validator from 'models/validator.js'; -import authorization from 'models/authorization.js'; -import removeMarkdown from 'models/remove-markdown.js'; +import { Box, Button, Confetti, Content, DefaultLayout, Link, TabCoinButtons, Tooltip } from '@/TabNewsUI'; +import { CommentDiscussionIcon, CommentIcon, FoldIcon, UnfoldIcon } from '@primer/octicons-react'; import { NotFoundError } from 'errors/index.js'; -import { Box, Button, Tooltip } from '@primer/react'; -import { CommentIcon, CommentDiscussionIcon, FoldIcon, UnfoldIcon } from '@primer/octicons-react'; import webserver from 'infra/webserver.js'; +import authorization from 'models/authorization.js'; +import content from 'models/content.js'; +import removeMarkdown from 'models/remove-markdown.js'; +import user from 'models/user.js'; +import validator from 'models/validator.js'; +import { useCollapse } from 'pages/interface'; +import { useEffect, useState } from 'react'; +import useSWR from 'swr'; export default function Post({ contentFound: contentFoundFallback, @@ -74,7 +74,7 @@ export default function Post({ sx={{ borderWidth: 0, borderRightWidth: 1, - borderColor: 'border.muted', + borderColor: 'btn.activeBorder', borderStyle: 'dotted', width: '50%', height: '100%', @@ -82,7 +82,7 @@ export default function Post({ /> - + @@ -246,7 +246,7 @@ function RenderChildrenTree({ childrenList, renderIntent, renderIncrement }) { borderStyle: 'dashed', }, svg: { - backgroundColor: 'white', + backgroundColor: 'canvas.default', }, }, }}> @@ -266,7 +266,7 @@ function RenderChildrenTree({ childrenList, renderIntent, renderIncrement }) { borderWidth: 0, borderRightWidth: 1, borderLeftWidth: 0, - borderColor: 'border.muted', + borderColor: 'btn.activeBorder', borderStyle: 'dotted', width: 0, transition: 'border 0.1s cubic-bezier(1,1,1,0)', @@ -275,7 +275,7 @@ function RenderChildrenTree({ childrenList, renderIntent, renderIncrement }) { - + diff --git a/pages/[username]/index.public.js b/pages/[username]/index.public.js index 0ac16739f..e3e486b06 100644 --- a/pages/[username]/index.public.js +++ b/pages/[username]/index.public.js @@ -1,16 +1,28 @@ -import useSWR from 'swr'; -import { useState } from 'react'; -import { DefaultLayout, ContentList, useUser } from 'pages/interface/index.js'; -import user from 'models/user.js'; -import content from 'models/content.js'; +import { + ActionList, + ActionMenu, + Box, + ContentList, + DefaultLayout, + Flash, + IconButton, + Label, + LabelGroup, + Pagehead, + useConfirm, +} from '@/TabNewsUI'; +import { KebabHorizontalIcon, TrashIcon } from '@primer/octicons-react'; +import { NotFoundError } from 'errors/index.js'; import authorization from 'models/authorization.js'; -import validator from 'models/validator.js'; +import content from 'models/content.js'; import removeMarkdown from 'models/remove-markdown.js'; -import { NotFoundError } from 'errors/index.js'; -import { FaUser } from 'react-icons/fa'; +import user from 'models/user.js'; +import validator from 'models/validator.js'; import { useRouter } from 'next/router'; -import { Box, Pagehead, ActionMenu, ActionList, Flash, IconButton, useConfirm, LabelGroup, Label } from '@primer/react'; -import { KebabHorizontalIcon, TrashIcon } from '@primer/octicons-react'; +import { useUser } from 'pages/interface'; +import { useState } from 'react'; +import { FaUser } from 'react-icons/fa'; +import useSWR from 'swr'; export default function Home({ contentListFound, pagination, userFound: userFoundFallback }) { const { data: userFound, mutate: userFoundMutate } = useSWR(`/api/v1/users/${userFoundFallback.username}`, { diff --git a/pages/[username]/pagina/[page]/index.public.js b/pages/[username]/pagina/[page]/index.public.js index 9788ede1a..d478cb8c3 100644 --- a/pages/[username]/pagina/[page]/index.public.js +++ b/pages/[username]/pagina/[page]/index.public.js @@ -1,4 +1,4 @@ -import { DefaultLayout, ContentList } from 'pages/interface/index.js'; +import { DefaultLayout, ContentList } from '@/TabNewsUI'; import user from 'models/user.js'; import content from 'models/content.js'; import authorization from 'models/authorization.js'; diff --git a/pages/_app.public.js b/pages/_app.public.js index ec9ff3571..6478d1c79 100644 --- a/pages/_app.public.js +++ b/pages/_app.public.js @@ -1,9 +1,7 @@ -import { ThemeProvider, BaseStyles, SSRProvider } from '@primer/react'; +import { ThemeProvider } from '@/TabNewsUI'; import { Analytics } from '@vercel/analytics/react'; +import { DefaultHead, UserProvider } from 'pages/interface'; import { SWRConfig } from 'swr'; -import { UserProvider } from 'pages/interface/hooks/useUser/index.js'; -import NextNProgress from 'pages/interface/components/Progressbar/index.js'; -import { DefaultHead } from 'pages/interface/components/Head/index.js'; async function SWRFetcher(resource, init) { const response = await fetch(resource, init); @@ -14,25 +12,15 @@ async function SWRFetcher(resource, init) { function MyApp({ Component, pageProps }) { return ( - <> - - - - - - - - - - - - - + + + + + + + - + ); } diff --git a/pages/_document.public.js b/pages/_document.public.js index 222e690bf..01c85dc54 100644 --- a/pages/_document.public.js +++ b/pages/_document.public.js @@ -1,6 +1,9 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document'; +import Document, { Head, Html, Main, NextScript } from 'next/document'; +import Script from 'next/script'; import { ServerStyleSheet } from 'styled-components'; +const noFlashScript = `document.documentElement.setAttribute('data-no-flash', true)`; + export default class MyDocument extends Document { static async getInitialProps(ctx) { const sheet = new ServerStyleSheet(); @@ -32,6 +35,9 @@ export default class MyDocument extends Document { +
diff --git a/pages/cadastro/ativar/[token].public.js b/pages/cadastro/ativar/[token].public.js index 7fc83672e..00aea7099 100644 --- a/pages/cadastro/ativar/[token].public.js +++ b/pages/cadastro/ativar/[token].public.js @@ -1,8 +1,7 @@ +import { Box, Confetti, DefaultLayout, Flash } from '@/TabNewsUI'; import fetch from 'cross-fetch'; -import { Box, Flash } from '@primer/react'; -import { DefaultLayout, Confetti } from 'pages/interface/index.js'; -import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; export default function ActiveUser() { const router = useRouter(); diff --git a/pages/cadastro/confirmar/index.public.js b/pages/cadastro/confirmar/index.public.js index 6d0a3d608..2e236d269 100644 --- a/pages/cadastro/confirmar/index.public.js +++ b/pages/cadastro/confirmar/index.public.js @@ -1,6 +1,5 @@ -import { Box, Heading, Text } from '@primer/react'; -import { useState, useEffect } from 'react'; -import { DefaultLayout } from 'pages/interface/index.js'; +import { Box, DefaultLayout, Heading, Text } from '@/TabNewsUI'; +import { useEffect, useState } from 'react'; export default function ConfirmSignup() { const [email, setEmail] = useState(''); diff --git a/pages/cadastro/index.public.js b/pages/cadastro/index.public.js index ecc94faf3..b95c0b232 100644 --- a/pages/cadastro/index.public.js +++ b/pages/cadastro/index.public.js @@ -1,7 +1,6 @@ -import { useState, useRef } from 'react'; +import { Box, Button, DefaultLayout, Flash, FormControl, Heading, PasswordInput, TextInput } from '@/TabNewsUI'; import { useRouter } from 'next/router'; -import { DefaultLayout, PasswordInput } from 'pages/interface/index.js'; -import { FormControl, Box, Heading, Button, TextInput, Flash } from '@primer/react'; +import { useRef, useState } from 'react'; export default function Register() { return ( @@ -111,7 +110,8 @@ function SignUpForm() { spellCheck={false} block={true} aria-label="Seu nome de usuário" - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', px: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} /> {errorObject?.key === 'username' && ( {errorObject.message} @@ -133,7 +133,8 @@ function SignUpForm() { spellCheck={false} block={true} aria-label="Seu email" - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', px: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} /> {errorObject?.key === 'email' && ( {errorObject.message} diff --git a/pages/cadastro/recuperar/[token].public.js b/pages/cadastro/recuperar/[token].public.js index ff3a6e5c4..1c6e072bd 100644 --- a/pages/cadastro/recuperar/[token].public.js +++ b/pages/cadastro/recuperar/[token].public.js @@ -1,8 +1,7 @@ -import { useState, useRef } from 'react'; +import { Box, Button, DefaultLayout, Flash, FormControl, Heading, PasswordInput } from '@/TabNewsUI'; import fetch from 'cross-fetch'; -import { FormControl, Box, Heading, Button, Flash } from '@primer/react'; -import { DefaultLayout, PasswordInput } from 'pages/interface/index.js'; import { useRouter } from 'next/router'; +import { useRef, useState } from 'react'; export default function RecoverPassword() { return ( diff --git a/pages/cadastro/recuperar/confirmar/index.public.js b/pages/cadastro/recuperar/confirmar/index.public.js index 9452e7194..980f0c124 100644 --- a/pages/cadastro/recuperar/confirmar/index.public.js +++ b/pages/cadastro/recuperar/confirmar/index.public.js @@ -1,5 +1,4 @@ -import { Box, Heading, Text } from '@primer/react'; -import { DefaultLayout } from 'pages/interface/index.js'; +import { Box, DefaultLayout, Heading, Text } from '@/TabNewsUI'; export default function ConfirmRecoverPassword() { return ( diff --git a/pages/cadastro/recuperar/index.public.js b/pages/cadastro/recuperar/index.public.js index 074105c28..4b442d9d6 100644 --- a/pages/cadastro/recuperar/index.public.js +++ b/pages/cadastro/recuperar/index.public.js @@ -1,7 +1,7 @@ -import { useState, useRef, useEffect } from 'react'; +import { Box, Button, DefaultLayout, Flash, FormControl, Heading, TextInput } from '@/TabNewsUI'; import { useRouter } from 'next/router'; -import { DefaultLayout, useUser } from 'pages/interface/index.js'; -import { FormControl, Box, Heading, Button, TextInput, Flash } from '@primer/react'; +import { useUser } from 'pages/interface'; +import { useEffect, useRef, useState } from 'react'; export default function RecoverPassword() { return ( @@ -110,6 +110,8 @@ function RecoverPasswordForm() { Digite seu e-mail ou o nome de usuário da pessoa que deseja ajudar Digite seu e-mail Título {errorObject?.key === 'body' && ( @@ -442,6 +448,8 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor Fonte (opcional) + {metadata && }
- + ); } diff --git a/pages/interface/components/EmptyState/index.js b/pages/interface/components/EmptyState/index.js index 5f64f51f1..6087cb6e0 100644 --- a/pages/interface/components/EmptyState/index.js +++ b/pages/interface/components/EmptyState/index.js @@ -1,18 +1,11 @@ -import { Text, Heading, Box, Button } from '@primer/react'; +import { Box, Button, Heading, Text } from '@/TabNewsUI'; import { PlusIcon } from '@primer/octicons-react'; export default function EmptyState(props) { const { title, description, action, icon: Icon, isLoading } = props; - + if (isLoading) return null; return ( - + {Icon && } {title} {description && {description}} diff --git a/pages/interface/components/Footer/index.js b/pages/interface/components/Footer/index.js index 5a88077e2..cb768cfd0 100644 --- a/pages/interface/components/Footer/index.js +++ b/pages/interface/components/Footer/index.js @@ -1,5 +1,4 @@ -import { Box } from '@primer/react'; -import { Link } from 'pages/interface'; +import { Box, Link } from '@/TabNewsUI'; import { CgTab } from 'react-icons/cg'; export default function Footer(props) { diff --git a/pages/interface/components/GoToTopButton/index.js b/pages/interface/components/GoToTopButton/index.js index 9390a0b70..3c7aa9e8e 100644 --- a/pages/interface/components/GoToTopButton/index.js +++ b/pages/interface/components/GoToTopButton/index.js @@ -1,5 +1,5 @@ +import { IconButton } from '@/TabNewsUI'; import { ChevronUpIcon } from '@primer/octicons-react'; -import { IconButton } from '@primer/react'; import { useEffect, useState } from 'react'; export default function GoToTopButton() { diff --git a/pages/interface/components/Head/index.js b/pages/interface/components/Head/index.js index d5f77a8a0..bf902b2fd 100644 --- a/pages/interface/components/Head/index.js +++ b/pages/interface/components/Head/index.js @@ -1,7 +1,7 @@ +import { useMediaQuery } from 'pages/interface'; import webserver from 'infra/webserver.js'; import NextHead from 'next/head'; import { useRouter } from 'next/router'; -import { useMediaQuery } from 'pages/interface/index.js'; const webserverHost = webserver.host; @@ -18,10 +18,9 @@ export function DefaultHead() { description: 'Conteúdos com valor concreto para quem trabalha com tecnologia.', url: `${webserverHost}${router.asPath}`, type: 'website', - noIndex: false, }; - const { type, title, description, image, url, noIndex } = defaultMetadata; + const { type, title, description, image, url } = defaultMetadata; return ( diff --git a/pages/interface/components/Header/index.js b/pages/interface/components/Header/index.js index e69bfe40f..baee75183 100644 --- a/pages/interface/components/Header/index.js +++ b/pages/interface/components/Header/index.js @@ -1,8 +1,21 @@ -import { Header, Box, ActionMenu, ActionList, IconButton, Truncate, Text, Tooltip } from '@primer/react'; -import { PersonFillIcon, HomeIcon, SquareFillIcon } from '@primer/octicons-react'; -import { CgTab } from 'react-icons/cg'; -import { HeaderLink, Link, useUser } from 'pages/interface'; +import { + ActionList, + ActionMenu, + Box, + HeaderLink, + IconButton, + Link, + PrimerHeader, + Text, + ThemeSelector, + ThemeSwitcher, + Tooltip, + Truncate, +} from '@/TabNewsUI'; +import { HomeIcon, PersonFillIcon, SquareFillIcon } from '@primer/octicons-react'; import { useRouter } from 'next/router'; +import { useUser } from 'pages/interface'; +import { CgTab } from 'react-icons/cg'; export default function HeaderComponent() { const { user, isLoading, logout } = useUser(); @@ -14,72 +27,78 @@ export default function HeaderComponent() { }; return ( - + ); } diff --git a/pages/interface/components/Link/index.js b/pages/interface/components/Link/index.js index 42cb043c2..b277dd881 100644 --- a/pages/interface/components/Link/index.js +++ b/pages/interface/components/Link/index.js @@ -1,5 +1,5 @@ +import { NavList, PrimerHeader, PrimerLink } from '@/TabNewsUI'; import NextLink from 'next/link'; -import { Header, Link as PrimerLink, NavList } from '@primer/react'; import { useRouter } from 'next/router'; export function Link({ href, children, ...props }) { @@ -12,9 +12,9 @@ export function Link({ href, children, ...props }) { export function HeaderLink({ href, children, ...props }) { return ( - + {children} - + ); } diff --git a/pages/interface/components/Markdown/index.js b/pages/interface/components/Markdown/index.js index f47e79f3d..0580c749c 100644 --- a/pages/interface/components/Markdown/index.js +++ b/pages/interface/components/Markdown/index.js @@ -1,21 +1,18 @@ -import { Viewer as ByteMdViewer, Editor as ByteMdEditor } from '@bytemd/react'; -import { Box } from '@primer/react'; +import { Box, EditorColors, EditorStyles } from '@/TabNewsUI'; +import { Editor as ByteMdEditor, Viewer as ByteMdViewer } from '@bytemd/react'; import { useEffect, useRef } from 'react'; // ByteMD dependencies: -import gfmPlugin from '@bytemd/plugin-gfm'; -import highlightSsrPlugin from '@bytemd/plugin-highlight-ssr'; -import mathPlugin from '@bytemd/plugin-math'; -import mermaidPlugin from '@bytemd/plugin-mermaid'; import breaksPlugin from '@bytemd/plugin-breaks'; import gemojiPlugin from '@bytemd/plugin-gemoji'; -import byteMDLocale from 'bytemd/locales/pt_BR.json'; +import gfmPlugin from '@bytemd/plugin-gfm'; import gfmLocale from '@bytemd/plugin-gfm/locales/pt_BR.json'; +import highlightSsrPlugin from '@bytemd/plugin-highlight-ssr'; +import mathPlugin from '@bytemd/plugin-math'; import mathLocale from '@bytemd/plugin-math/locales/pt_BR.json'; +import mermaidPlugin from '@bytemd/plugin-mermaid'; import mermaidLocale from '@bytemd/plugin-mermaid/locales/pt_BR.json'; -import 'bytemd/dist/index.min.css'; -import 'highlight.js/styles/github.css'; -import 'github-markdown-css/github-markdown-light.css'; +import byteMDLocale from 'bytemd/locales/pt_BR.json'; import 'katex/dist/katex.css'; const bytemdPluginList = [ @@ -35,7 +32,8 @@ export default function Viewer({ ...props }) { } // Editor is not part of Primer, so error messages and styling need to be created manually -export function Editor({ isValid, onKeyDown, ...props }) { +export function Editor({ isValid, onKeyDown, compact, ...props }) { + const editorMode = 'split'; // 'tab' const editorRef = useRef(); useEffect(() => { @@ -44,56 +42,18 @@ export function Editor({ isValid, onKeyDown, ...props }) { return () => editorElement?.removeEventListener('keydown', onKeyDown); }, [onKeyDown]); + useEffect(() => { + editorRef.current + ?.getElementsByClassName('bytemd-toolbar-right')[0] + ?.querySelector('[bytemd-tippy-path="2"]') + ?.click(); + }, []); + return ( - - - + + + ); } diff --git a/pages/interface/components/Markdown/styles/index.js b/pages/interface/components/Markdown/styles/index.js new file mode 100644 index 000000000..9e641a0ef --- /dev/null +++ b/pages/interface/components/Markdown/styles/index.js @@ -0,0 +1,1913 @@ +import { useTheme } from '@/TabNewsUI'; + +export function EditorColors() { + const { + theme: { colors, shadows }, + } = useTheme(); + + if (!colors || !shadows) return null; + + return ( + + ); +} + +export function EditorStyles({ mode, compact }) { + return ( + + ); +} + +export function ViewerStyles() { + // based on "highlight.js" and "github-markdown-css" + + const { + resolvedColorScheme, + theme: { colors, shadows }, + } = useTheme(); + + if (!colors || !shadows) return null; + + return ( + + ); +} diff --git a/pages/interface/components/PasswordInput/index.js b/pages/interface/components/PasswordInput/index.js index 1e56d2d2b..9ef13a8e5 100644 --- a/pages/interface/components/PasswordInput/index.js +++ b/pages/interface/components/PasswordInput/index.js @@ -1,6 +1,6 @@ -import { useEffect, useState } from 'react'; -import { FormControl, TextInput } from '@primer/react'; +import { FormControl, TextInput } from '@/TabNewsUI'; import { EyeClosedIcon, EyeIcon } from '@primer/octicons-react'; +import { useEffect, useState } from 'react'; export default function PasswordInput({ inputRef, id, name, label, errorObject, setErrorObject, ...props }) { const [isPasswordVisible, setIsPasswordVisible] = useState(false); @@ -52,7 +52,8 @@ export default function PasswordInput({ inputRef, id, name, label, errorObject, sx={{ color: 'fg.subtle' }} /> } - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', pl: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} ref={inputRef} onChange={clearErrors} onKeyDown={detectCapsLock} diff --git a/pages/interface/components/PublishedSince/index.js b/pages/interface/components/PublishedSince/index.js index e0bf210f0..d346bb404 100644 --- a/pages/interface/components/PublishedSince/index.js +++ b/pages/interface/components/PublishedSince/index.js @@ -1,6 +1,6 @@ -import { formatDistanceToNowStrict, format } from 'date-fns'; +import { Tooltip } from '@/TabNewsUI'; +import { format, formatDistanceToNowStrict } from 'date-fns'; import { ptBR } from 'date-fns/locale'; -import { Tooltip } from '@primer/react'; import { useEffect, useState } from 'react'; function formatPublishedSince(date) { diff --git a/pages/interface/components/TabCoinButtons/index.js b/pages/interface/components/TabCoinButtons/index.js index 002161f6c..b185fc0d6 100644 --- a/pages/interface/components/TabCoinButtons/index.js +++ b/pages/interface/components/TabCoinButtons/index.js @@ -1,10 +1,9 @@ -import { useState, useEffect } from 'react'; -import { Box, Text, IconButton, Tooltip } from '@primer/react'; -import { ChevronUpIcon, ChevronDownIcon } from '@primer/octicons-react'; -import { useReward } from 'react-rewards'; +import { Box, IconButton, Text, Tooltip } from '@/TabNewsUI'; +import { ChevronDownIcon, ChevronUpIcon } from '@primer/octicons-react'; import { useRouter } from 'next/router'; - -import { useUser } from 'pages/interface/index.js'; +import { useUser } from 'pages/interface'; +import { useEffect, useState } from 'react'; +import { useReward } from 'react-rewards'; export default function TabCoinButtons({ content }) { const router = useRouter(); diff --git a/pages/interface/components/TabNewsUI/index.js b/pages/interface/components/TabNewsUI/index.js new file mode 100644 index 000000000..197d7d998 --- /dev/null +++ b/pages/interface/components/TabNewsUI/index.js @@ -0,0 +1,45 @@ +export { default as Confetti } from '@/Confetti/index.js'; +export { default as Content } from '@/Content/index.js'; +export { default as ContentList } from '@/ContentList/index.js'; +export { default as DefaultLayout } from '@/DefaultLayout/index.js'; +export { default as EmptyState } from '@/EmptyState/index.js'; +export { default as Footer } from '@/Footer/index.js'; +export { default as GoToTopButton } from '@/GoToTopButton/index.js'; +export { default as Header } from '@/Header/index.js'; +export { default as NextLink, HeaderLink, Link, NavItem } from '@/Link'; +export { default as Viewer, Editor } from '@/Markdown/index.js'; +export { EditorColors, EditorStyles, ViewerStyles } from '@/Markdown/styles/index.js'; +export { default as PasswordInput } from '@/PasswordInput/index.js'; +export { default as NextNProgress } from '@/Progressbar/index.js'; +export { default as PublishedSince } from '@/PublishedSince/index.js'; +export { default as TabCoinButtons } from '@/TabCoinButtons/index.js'; +export { default as ThemeProvider } from '@/ThemeProvider/index.js'; +export { default as ThemeSelector, ThemeSwitcher } from '@/ThemeSelector/index.js'; +export { + ActionList, + ActionMenu, + BaseStyles, + Box, + BranchName, + Button, + Checkbox, + Flash, + FormControl, + Header as PrimerHeader, + Heading, + IconButton, + Label, + LabelGroup, + Link as PrimerLink, + NavList, + Pagehead, + SegmentedControl, + SSRProvider, + Text, + TextInput, + ThemeProvider as PrimerThemeProvider, + Tooltip, + Truncate, + useConfirm, + useTheme, +} from '@primer/react'; diff --git a/pages/interface/components/ThemeProvider/index.js b/pages/interface/components/ThemeProvider/index.js new file mode 100644 index 000000000..3526064ad --- /dev/null +++ b/pages/interface/components/ThemeProvider/index.js @@ -0,0 +1,32 @@ +import { BaseStyles, NextNProgress, PrimerThemeProvider, SSRProvider, ViewerStyles } from '@/TabNewsUI'; +import { useEffect, useLayoutEffect, useState } from 'react'; +import { createGlobalStyle } from 'styled-components'; + +// script to be called before interactive in _document.js +// document.documentElement.setAttribute('data-no-flash', true) +const NoFleshGlobalStyle = createGlobalStyle`html[data-no-flash='true']:root {visibility: hidden}`; +const removeNoFlashStyle = () => setTimeout(() => document.documentElement.removeAttribute('data-no-flash')); +const useBrowserLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect; + +export default function ThemeProvider({ children, defaultColorMode, ...props }) { + const [colorMode, setColorMode] = useState(defaultColorMode === 'night' ? 'night' : 'day'); + + useBrowserLayoutEffect(() => { + const cachedColorMode = localStorage.getItem('colorMode') || colorMode; + setColorMode(cachedColorMode); + removeNoFlashStyle(); + }, []); + + return ( + + + + + + {children} + + + + + ); +} diff --git a/pages/interface/components/ThemeSelector/index.js b/pages/interface/components/ThemeSelector/index.js new file mode 100644 index 000000000..4762fa80a --- /dev/null +++ b/pages/interface/components/ThemeSelector/index.js @@ -0,0 +1,66 @@ +import { Box, Button, SegmentedControl, useTheme } from '@/TabNewsUI'; +import { MoonIcon, SunIcon } from '@primer/octicons-react'; + +export default function ThemeSelector({ ...props }) { + const { colorMode, setColorMode } = useTheme(); + + const handleChangeColorMode = (mode) => { + setColorMode(mode); + localStorage.setItem('colorMode', mode); + }; + + return ( + + + handleChangeColorMode('night')} + icon={MoonIcon} + size="small" + /> + handleChangeColorMode('auto')} + size="small"> + Auto + + handleChangeColorMode('day')} + icon={SunIcon} + size="small" + /> + + + ); +} + +export function ThemeSwitcher({ ...props }) { + const { resolvedColorMode: mode, setColorMode } = useTheme(); + + const handleSwitchMode = () => { + const newMode = mode === 'day' ? 'night' : 'day'; + setColorMode(newMode); + localStorage.setItem('colorMode', newMode); + }; + + return ( + + ); +} diff --git a/pages/interface/index.js b/pages/interface/index.js index aa06f8557..ce053499f 100644 --- a/pages/interface/index.js +++ b/pages/interface/index.js @@ -1,18 +1,4 @@ -export { default as DefaultLayout } from './components/DefaultLayout/index.js'; -export { default as Header } from './components/Header/index.js'; -export { default as Content } from './components/Content/index.js'; -export { default as ContentList } from './components/ContentList/index.js'; -export { default as Footer } from './components/Footer/index.js'; -export { default as Head } from './components/Head/index.js'; -export { default as TabCoinButtons } from './components/TabCoinButtons/index.js'; -export { default as PublishedSince } from './components/PublishedSince/index.js'; -export { default as EmptyState } from './components/EmptyState/index.js'; -export { default as Confetti } from './components/Confetti/index.js'; -export { default as NextLink, HeaderLink, Link, NavItem } from './components/Link/index.js'; -export { default as GoToTopButton } from './components/GoToTopButton/index.js'; -export { default as Viewer, Editor } from './components/Markdown/index.js'; -export { default as PasswordInput } from './components/PasswordInput/index.js'; - +export { default as Head, DefaultHead } from './components/Head/index.js'; export { default as useCollapse } from './hooks/useCollapse/index.js'; -export { default as useUser } from './hooks/useUser/index.js'; export { default as useMediaQuery } from './hooks/useMediaQuery/index.js'; +export { default as useUser, UserProvider } from './hooks/useUser/index.js'; diff --git a/pages/login/index.public.js b/pages/login/index.public.js index 82d4d87aa..8131cf9e5 100644 --- a/pages/login/index.public.js +++ b/pages/login/index.public.js @@ -1,7 +1,18 @@ -import { useState, useRef, useEffect } from 'react'; +import { + Box, + Button, + DefaultLayout, + Flash, + FormControl, + Heading, + Link, + PasswordInput, + Text, + TextInput, +} from '@/TabNewsUI'; import { useRouter } from 'next/router'; -import { DefaultLayout, useUser, PasswordInput } from 'pages/interface/index.js'; -import { FormControl, Box, Heading, Button, TextInput, Flash, Link, Text } from '@primer/react'; +import { useUser } from 'pages/interface'; +import { useEffect, useRef, useState } from 'react'; export default function Login() { return ( @@ -104,7 +115,8 @@ function LoginForm() { spellCheck={false} block={true} aria-label="Seu email" - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', px: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} /> {errorObject?.key === 'email' && ( {errorObject.message} diff --git a/pages/museu/index.public.js b/pages/museu/index.public.js index f3342daca..dd772d645 100644 --- a/pages/museu/index.public.js +++ b/pages/museu/index.public.js @@ -1,5 +1,4 @@ -import { Box, Link, Text } from '@primer/react'; -import { DefaultLayout } from 'pages/interface'; +import { Box, DefaultLayout, PrimerLink, Text } from '@/TabNewsUI'; export default function Page() { return ( @@ -19,75 +18,75 @@ export default function Page() {
  • - Primeira Home Oficial (Init) feito pelos Membros da Turma + Primeira Home Oficial (Init) feito pelos Membros da Turma
  • - Em Construção POC #01 feito por{' '} - Rodrigo Kulb + Em Construção POC #01 feito por{' '} + Rodrigo Kulb
  • - Em Construção POC #03 feito por{' '} - Bruno Familiar + Em Construção POC #03 feito por{' '} + Bruno Familiar
  • - Home POC #01 feito por{' '} - Filipe Deschamps + Home POC #01 feito por{' '} + Filipe Deschamps
  • - Home POC #02 feito por{' '} - Filipe Deschamps + Home POC #02 feito por{' '} + Filipe Deschamps
  • - Home POC #03 feito por{' '} - Filipe Deschamps + Home POC #03 feito por{' '} + Filipe Deschamps
  • - Home POC #04 feito por{' '} - Filipe Deschamps + Home POC #04 feito por{' '} + Filipe Deschamps
  • - Home POC #05 feito por{' '} - Filipe Deschamps + Home POC #05 feito por{' '} + Filipe Deschamps
  • - Home POC #06 feito por{' '} - Filipe Deschamps + Home POC #06 feito por{' '} + Filipe Deschamps
  • - Home POC #07 feito por{' '} - Filipe Deschamps + Home POC #07 feito por{' '} + Filipe Deschamps
  • - Home POC #08 feito por{' '} - Filipe Deschamps + Home POC #08 feito por{' '} + Filipe Deschamps
  • - Home POC #09 - Dark Mode feito por{' '} - Pedro Cruz + Home POC #09 - Dark Mode feito por{' '} + Pedro Cruz
  • - Home POC #10 feito por{' '} - Guilhermo Masid + Home POC #10 feito por{' '} + Guilhermo Masid
  • - Home POC #10 - Mobile feito por{' '} - Rodrigo Kulb + Home POC #10 - Mobile feito por{' '} + Rodrigo Kulb
  • - Home POC #11 feito por{' '} - Pedro Cruz + Home POC #11 feito por{' '} + Pedro Cruz
  • - Home POC #12 feito por{' '} - Luan Tonin Galvan + Home POC #12 feito por{' '} + Luan Tonin Galvan
  • - Post POC #01 feito por{' '} - Filipe Deschamps + Post POC #01 feito por{' '} + Filipe Deschamps
  • - Post POC #02 feito por{' '} - Pedro Cruz + Post POC #02 feito por{' '} + Pedro Cruz
diff --git a/pages/pagina/[page]/index.public.js b/pages/pagina/[page]/index.public.js index 28f54297c..6d30118cc 100644 --- a/pages/pagina/[page]/index.public.js +++ b/pages/pagina/[page]/index.public.js @@ -1,7 +1,7 @@ -import { DefaultLayout, ContentList } from 'pages/interface/index.js'; -import user from 'models/user.js'; -import content from 'models/content.js'; +import { ContentList, DefaultLayout } from '@/TabNewsUI'; import authorization from 'models/authorization.js'; +import content from 'models/content.js'; +import user from 'models/user.js'; import validator from 'models/validator.js'; export default function Home({ contentListFound, pagination }) { diff --git a/pages/perfil/confirmar-email/[token].public.js b/pages/perfil/confirmar-email/[token].public.js index 2973e33fd..a9af7fff8 100644 --- a/pages/perfil/confirmar-email/[token].public.js +++ b/pages/perfil/confirmar-email/[token].public.js @@ -1,8 +1,7 @@ +import { Box, Confetti, DefaultLayout, Flash } from '@/TabNewsUI'; import fetch from 'cross-fetch'; -import { Box, Flash } from '@primer/react'; -import { DefaultLayout, Confetti } from 'pages/interface/index.js'; -import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; export default function ActiveUser() { const router = useRouter(); diff --git a/pages/perfil/index.public.js b/pages/perfil/index.public.js index 4507a7093..b2d21547e 100644 --- a/pages/perfil/index.public.js +++ b/pages/perfil/index.public.js @@ -1,7 +1,18 @@ -import { useState, useRef, useEffect } from 'react'; +import { + Box, + Button, + Checkbox, + DefaultLayout, + Flash, + FormControl, + Heading, + Link, + TextInput, + useConfirm, +} from '@/TabNewsUI'; +import { useUser } from 'pages/interface'; import { useRouter } from 'next/router'; -import { DefaultLayout, useUser, Link } from 'pages/interface/index.js'; -import { FormControl, Box, Heading, Button, TextInput, Checkbox, Flash, useConfirm } from '@primer/react'; +import { useEffect, useRef, useState } from 'react'; export default function EditProfile() { return ( @@ -168,7 +179,8 @@ function EditProfileForm() { spellCheck={false} block={true} aria-label="Seu nome de usuário" - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', px: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} /> {errorObject?.key === 'username' && ( {errorObject.message} @@ -191,7 +203,8 @@ function EditProfileForm() { spellCheck={false} block={true} aria-label="Seu email" - sx={{ minHeight: '46px' }} + contrast + sx={{ minHeight: '46px', px: 2, '&:focus-within': { backgroundColor: 'canvas.default' } }} /> {errorObject?.key === 'email' && !errorObject?.type && ( {errorObject.message} diff --git a/pages/publicar/index.public.js b/pages/publicar/index.public.js index 5086791b8..f2800fdfe 100644 --- a/pages/publicar/index.public.js +++ b/pages/publicar/index.public.js @@ -1,8 +1,8 @@ -import useSWR from 'swr'; +import { Box, Content, DefaultLayout, Flash, Heading, Link } from '@/TabNewsUI'; import { useRouter } from 'next/router'; -import { DefaultLayout, Content, useUser } from 'pages/interface/index.js'; -import { Box, Heading, Flash, Link } from '@primer/react'; +import { useUser } from 'pages/interface'; import { useEffect } from 'react'; +import useSWR from 'swr'; export default function Post() { const router = useRouter(); diff --git a/pages/recentes/index.public.js b/pages/recentes/index.public.js index de8412044..81fc5766c 100644 --- a/pages/recentes/index.public.js +++ b/pages/recentes/index.public.js @@ -1,7 +1,7 @@ -import { DefaultLayout, ContentList } from 'pages/interface/index.js'; -import user from 'models/user.js'; -import content from 'models/content.js'; +import { ContentList, DefaultLayout } from '@/TabNewsUI'; import authorization from 'models/authorization.js'; +import content from 'models/content.js'; +import user from 'models/user.js'; import validator from 'models/validator.js'; export default function Home({ contentListFound, pagination }) { diff --git a/pages/recentes/pagina/[page]/index.public.js b/pages/recentes/pagina/[page]/index.public.js index db202c01c..45c60f580 100644 --- a/pages/recentes/pagina/[page]/index.public.js +++ b/pages/recentes/pagina/[page]/index.public.js @@ -1,7 +1,7 @@ -import { DefaultLayout, ContentList } from 'pages/interface/index.js'; -import user from 'models/user.js'; -import content from 'models/content.js'; +import { ContentList, DefaultLayout } from '@/TabNewsUI'; import authorization from 'models/authorization.js'; +import content from 'models/content.js'; +import user from 'models/user.js'; import validator from 'models/validator.js'; export default function Home({ contentListFound, pagination }) { diff --git a/pages/status/index.public.js b/pages/status/index.public.js index a8b75e9f6..61b491ce1 100644 --- a/pages/status/index.public.js +++ b/pages/status/index.public.js @@ -1,8 +1,6 @@ +import { Box, DefaultLayout, Heading, Label, LabelGroup, Truncate } from '@/TabNewsUI'; +import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis } from 'recharts'; import useSWR from 'swr'; -import { Box, Heading, Label, LabelGroup, Truncate } from '@primer/react'; -import { ResponsiveContainer, BarChart, Bar, Tooltip, XAxis } from 'recharts'; - -import { DefaultLayout } from 'pages/interface/index.js'; export default function Page() { const { data: statusObject, isLoading: statusObjectIsLoading } = useSWR('/api/v1/status', { diff --git a/pages/termos-de-uso/index.public.js b/pages/termos-de-uso/index.public.js index da0d5d368..7adf7126b 100644 --- a/pages/termos-de-uso/index.public.js +++ b/pages/termos-de-uso/index.public.js @@ -1,7 +1,4 @@ -import { Box, Heading } from '@primer/react'; -import { Viewer } from 'pages/interface'; - -import { DefaultLayout } from 'pages/interface/index.js'; +import { Box, DefaultLayout, Heading, Viewer } from '@/TabNewsUI'; export default function Page() { const body = `Ao utilizar o TabNews você está de acordo com os seguintes termos: