Merge pull request #11 from Accords-Library/develop
Now using Tippy for Tooltips + prettier integration
This commit is contained in:
commit
55c267490a
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
.next
|
@ -14,6 +14,7 @@
|
|||||||
- Markdown format for the rich text fields
|
- Markdown format for the rich text fields
|
||||||
|
|
||||||
#### [Image Processor](https://github.com/Accords-Library/img.accords-library.com)
|
#### [Image Processor](https://github.com/Accords-Library/img.accords-library.com)
|
||||||
|
|
||||||
- Convert the images from the CMS to 4 formats
|
- Convert the images from the CMS to 4 formats
|
||||||
- Small: 512x512, quality 60, .webp
|
- Small: 512x512, quality 60, .webp
|
||||||
- Medium: 1024x1024, quality 75, .webp
|
- Medium: 1024x1024, quality 75, .webp
|
||||||
|
10
next-env.d.ts
vendored
10
next-env.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||||
|
99
package-lock.json
generated
99
package-lock.json
generated
@ -11,12 +11,12 @@
|
|||||||
"@fontsource/opendyslexic": "^4.5.2",
|
"@fontsource/opendyslexic": "^4.5.2",
|
||||||
"@fontsource/vollkorn": "^4.5.4",
|
"@fontsource/vollkorn": "^4.5.4",
|
||||||
"@fontsource/zen-maru-gothic": "^4.5.5",
|
"@fontsource/zen-maru-gothic": "^4.5.5",
|
||||||
|
"@tippyjs/react": "^4.2.6",
|
||||||
"markdown-to-jsx": "^7.1.7",
|
"markdown-to-jsx": "^7.1.7",
|
||||||
"next": "^12.1.0",
|
"next": "^12.1.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-swipeable": "^6.2.0",
|
"react-swipeable": "^6.2.0",
|
||||||
"react-tooltip": "^4.2.21",
|
|
||||||
"turndown": "^7.1.1"
|
"turndown": "^7.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -448,12 +448,34 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.3.tgz",
|
||||||
|
"integrity": "sha512-8U7hIl7+30XbIrJ0deQMXpXESM1L4yrt6BHok5hzcR0LivivuNkk+tHU1iRVScOwCmQcrOr6kvtIr29MNbQHqQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
|
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/json5": {
|
"node_modules/@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
@ -2960,6 +2982,7 @@
|
|||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.4.0",
|
"loose-envify": "^1.4.0",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
@ -3035,7 +3058,8 @@
|
|||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/react-swipeable": {
|
"node_modules/react-swipeable": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
@ -3045,22 +3069,6 @@
|
|||||||
"react": "^16.8.3 || ^17"
|
"react": "^16.8.3 || ^17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-tooltip": {
|
|
||||||
"version": "4.2.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
|
||||||
"integrity": "sha512-zSLprMymBDowknr0KVDiJ05IjZn9mQhhg4PRsqln0OZtURAJ1snt1xi5daZfagsh6vfsziZrc9pErPTDY1ACig==",
|
|
||||||
"dependencies": {
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"uuid": "^7.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"npm": ">=6.13"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.0.0",
|
|
||||||
"react-dom": ">=16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/readdirp": {
|
"node_modules/readdirp": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
@ -3424,6 +3432,14 @@
|
|||||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@ -3555,14 +3571,6 @@
|
|||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "7.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
|
|
||||||
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/v8-compile-cache": {
|
"node_modules/v8-compile-cache": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
@ -3917,12 +3925,25 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.11.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.3.tgz",
|
||||||
|
"integrity": "sha512-8U7hIl7+30XbIrJ0deQMXpXESM1L4yrt6BHok5hzcR0LivivuNkk+tHU1iRVScOwCmQcrOr6kvtIr29MNbQHqQ=="
|
||||||
|
},
|
||||||
"@rushstack/eslint-patch": {
|
"@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
|
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"requires": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/json5": {
|
"@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
@ -5740,6 +5761,7 @@
|
|||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"loose-envify": "^1.4.0",
|
"loose-envify": "^1.4.0",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
@ -5786,7 +5808,8 @@
|
|||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"react-swipeable": {
|
"react-swipeable": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
@ -5794,15 +5817,6 @@
|
|||||||
"integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==",
|
"integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"react-tooltip": {
|
|
||||||
"version": "4.2.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
|
||||||
"integrity": "sha512-zSLprMymBDowknr0KVDiJ05IjZn9mQhhg4PRsqln0OZtURAJ1snt1xi5daZfagsh6vfsziZrc9pErPTDY1ACig==",
|
|
||||||
"requires": {
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"uuid": "^7.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"readdirp": {
|
"readdirp": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
@ -6043,6 +6057,14 @@
|
|||||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"requires": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"to-regex-range": {
|
"to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@ -6143,11 +6165,6 @@
|
|||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uuid": {
|
|
||||||
"version": "7.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
|
|
||||||
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="
|
|
||||||
},
|
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
"@fontsource/opendyslexic": "^4.5.2",
|
"@fontsource/opendyslexic": "^4.5.2",
|
||||||
"@fontsource/vollkorn": "^4.5.4",
|
"@fontsource/vollkorn": "^4.5.4",
|
||||||
"@fontsource/zen-maru-gothic": "^4.5.5",
|
"@fontsource/zen-maru-gothic": "^4.5.5",
|
||||||
|
"@tippyjs/react": "^4.2.6",
|
||||||
"markdown-to-jsx": "^7.1.7",
|
"markdown-to-jsx": "^7.1.7",
|
||||||
"next": "^12.1.0",
|
"next": "^12.1.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-swipeable": "^6.2.0",
|
"react-swipeable": "^6.2.0",
|
||||||
"react-tooltip": "^4.2.21",
|
|
||||||
"turndown": "^7.1.1"
|
"turndown": "^7.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -2,5 +2,5 @@ module.exports = {
|
|||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -21,4 +21,4 @@ Insert the following code in the `head` section of your pages:
|
|||||||
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
|
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
|
||||||
<meta name="theme-color" content="#feecd6">
|
<meta name="theme-color" content="#feecd6">
|
||||||
|
|
||||||
*Optional* - Check your favicon with the [favicon checker](https://realfavicongenerator.net/favicon_checker)
|
_Optional_ - Check your favicon with the [favicon checker](https://realfavicongenerator.net/favicon_checker)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
<link rel="manifest" href="/site.webmanifest">
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#9c6644">
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#9c6644" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Accord's Library">
|
<meta name="apple-mobile-web-app-title" content="Accord's Library" />
|
||||||
<meta name="application-name" content="Accord's Library">
|
<meta name="application-name" content="Accord's Library" />
|
||||||
<meta name="msapplication-TileColor" content="#feecd6">
|
<meta name="msapplication-TileColor" content="#feecd6" />
|
||||||
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
|
<meta name="msapplication-TileImage" content="/mstile-144x144.png" />
|
||||||
<meta name="theme-color" content="#feecd6">
|
<meta name="theme-color" content="#feecd6" />
|
||||||
|
1
run_accords_prettier.sh
Executable file
1
run_accords_prettier.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
npx prettier --end-of-line auto --write .
|
@ -7,9 +7,8 @@ import Head from "next/head";
|
|||||||
import { useSwipeable } from "react-swipeable";
|
import { useSwipeable } from "react-swipeable";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Button from "components/Button";
|
import Button from "components/Button";
|
||||||
import { getOgImage, OgImage, prettyLanguage } from "queries/helpers";
|
import { getOgImage, OgImage } from "queries/helpers";
|
||||||
import { useMediaCoarse, useMediaMobile } from "hooks/useMediaQuery";
|
import { useMediaCoarse, useMediaMobile } from "hooks/useMediaQuery";
|
||||||
import ReactTooltip from "react-tooltip";
|
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { ImageQuality } from "./Img";
|
import { ImageQuality } from "./Img";
|
||||||
import Popup from "./Popup";
|
import Popup from "./Popup";
|
||||||
@ -25,7 +24,6 @@ interface AppLayoutProps extends AppStaticProps {
|
|||||||
navTitle: string;
|
navTitle: string;
|
||||||
thumbnail?: StrapiImage;
|
thumbnail?: StrapiImage;
|
||||||
description?: string;
|
description?: string;
|
||||||
extra?: React.ReactNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
@ -56,27 +54,6 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mainPanelClass = `fixed desktop:left-0 desktop:top-0 desktop:bottom-0 ${
|
|
||||||
appLayout.mainPanelReduced ? "desktop:w-[6rem]" : "desktop:w-[20rem]"
|
|
||||||
}`;
|
|
||||||
const subPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:w-[20rem] ${
|
|
||||||
appLayout.mainPanelReduced ? " desktop:left-[6rem]" : "desktop:left-[20rem]"
|
|
||||||
}`;
|
|
||||||
let contentPanelClass = "";
|
|
||||||
if (subPanel) {
|
|
||||||
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
|
|
||||||
appLayout.mainPanelReduced
|
|
||||||
? "desktop:left-[26rem]"
|
|
||||||
: "desktop:left-[40rem]"
|
|
||||||
}`;
|
|
||||||
} else if (contentPanel) {
|
|
||||||
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
|
|
||||||
appLayout.mainPanelReduced
|
|
||||||
? "desktop:left-[6rem]"
|
|
||||||
: "desktop:left-[20rem]"
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const turnSubIntoContent = subPanel && !contentPanel;
|
const turnSubIntoContent = subPanel && !contentPanel;
|
||||||
|
|
||||||
const titlePrefix = "Accord’s Library";
|
const titlePrefix = "Accord’s Library";
|
||||||
@ -117,6 +94,21 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [currencySelect]);
|
}, [currencySelect]);
|
||||||
|
|
||||||
|
let gridCol = "";
|
||||||
|
if (props.subPanel) {
|
||||||
|
if (appLayout.mainPanelReduced) {
|
||||||
|
gridCol = "grid-cols-[6rem_20rem_1fr]";
|
||||||
|
} else {
|
||||||
|
gridCol = "grid-cols-[20rem_20rem_1fr]";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (appLayout.mainPanelReduced) {
|
||||||
|
gridCol = "grid-cols-[6rem_0px_1fr]";
|
||||||
|
} else {
|
||||||
|
gridCol = "grid-cols-[20rem_0px_1fr]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
@ -129,7 +121,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
{...handlers}
|
{...handlers}
|
||||||
className="fixed inset-0 touch-pan-y p-0 m-0 bg-light text-black"
|
className={`fixed inset-0 touch-pan-y p-0 m-0 bg-light text-black grid [grid-template-areas:'main_sub_content'] ${gridCol} mobile:grid-cols-[1fr] mobile:grid-rows-[1fr_5rem] mobile:[grid-template-areas:'content''navbar']`}
|
||||||
>
|
>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{`${titlePrefix} - ${ogTitle}`}</title>
|
<title>{`${titlePrefix} - ${ogTitle}`}</title>
|
||||||
@ -159,9 +151,32 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
<meta name="twitter:image" content={metaImage.image}></meta>
|
<meta name="twitter:image" content={metaImage.image}></meta>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
{/* Background when navbar is opened */}
|
||||||
|
<div
|
||||||
|
className={`[grid-area:content] mobile:z-10 absolute inset-0 transition-[backdrop-filter] duration-500 ${
|
||||||
|
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
||||||
|
? "[backdrop-filter:blur(2px)]"
|
||||||
|
: "pointer-events-none touch-none "
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`absolute bg-shade inset-0 transition-opacity duration-500
|
||||||
|
${turnSubIntoContent ? "" : ""}
|
||||||
|
${
|
||||||
|
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
||||||
|
? "opacity-60"
|
||||||
|
: "opacity-0"
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
appLayout.setMainPanelOpen(false);
|
||||||
|
appLayout.setSubPanelOpen(false);
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Content panel */}
|
{/* Content panel */}
|
||||||
<div
|
<div
|
||||||
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`}
|
className={`[grid-area:content] overflow-y-scroll bg-light texture-paper-dots`}
|
||||||
>
|
>
|
||||||
{contentPanel ? (
|
{contentPanel ? (
|
||||||
contentPanel
|
contentPanel
|
||||||
@ -175,38 +190,15 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Background when navbar is opened */}
|
|
||||||
<div
|
|
||||||
className={`fixed inset-0 transition-[backdrop-filter] duration-500 ${
|
|
||||||
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
|
||||||
? "[backdrop-filter:blur(2px)]"
|
|
||||||
: "pointer-events-none touch-none "
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`fixed bg-shade inset-0 transition-opacity duration-500
|
|
||||||
${turnSubIntoContent ? "z-10" : ""}
|
|
||||||
${
|
|
||||||
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
|
||||||
? "opacity-60"
|
|
||||||
: "opacity-0"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
appLayout.setMainPanelOpen(false);
|
|
||||||
appLayout.setSubPanelOpen(false);
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Sub panel */}
|
{/* Sub panel */}
|
||||||
{subPanel && (
|
{subPanel && (
|
||||||
<div
|
<div
|
||||||
className={`${subPanelClass} border-r-[1px] mobile:bottom-20 mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
className={`[grid-area:sub] mobile:[grid-area:content] mobile:z-10 mobile:w-[90%] mobile:justify-self-end border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
||||||
${
|
${
|
||||||
turnSubIntoContent
|
turnSubIntoContent
|
||||||
? "mobile:translate-x-0 mobile:left-0 mobile:border-l-0"
|
? "mobile:border-l-0 mobile:w-full"
|
||||||
: !appLayout.subPanelOpen
|
: !appLayout.subPanelOpen
|
||||||
? "mobile:translate-x-full"
|
? "mobile:translate-x-[100vw]"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@ -216,28 +208,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
|
|
||||||
{/* Main panel */}
|
{/* Main panel */}
|
||||||
<div
|
<div
|
||||||
className={`${mainPanelClass} border-r-[1px] mobile:bottom-20 border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots
|
className={`[grid-area:main] mobile:[grid-area:content] mobile:z-10 mobile:w-[90%] mobile:justify-self-start border-r-[1px] border-black border-dotted overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
||||||
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||||
>
|
>
|
||||||
<MainPanel langui={langui} />
|
<MainPanel langui={langui} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main panel minimize button*/}
|
|
||||||
<div
|
|
||||||
className={`mobile:hidden translate-x-0 fixed top-1/2 z-20 ${
|
|
||||||
appLayout.mainPanelReduced ? "left-[4.65rem]" : "left-[18.65rem]"
|
|
||||||
}`}
|
|
||||||
onClick={() =>
|
|
||||||
appLayout.setMainPanelReduced(!appLayout.mainPanelReduced)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button className="material-icons bg-light !px-2">
|
|
||||||
{appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Navbar */}
|
{/* Navbar */}
|
||||||
<div className="fixed inset-0 z-30 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
<div className="[grid-area:navbar] border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
||||||
<span
|
<span
|
||||||
className="material-icons mt-[.1em] cursor-pointer"
|
className="material-icons mt-[.1em] cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -413,20 +391,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
<ReactTooltip
|
|
||||||
id="MainPanelTooltip"
|
|
||||||
place="right"
|
|
||||||
type="light"
|
|
||||||
effect="solid"
|
|
||||||
delayShow={300}
|
|
||||||
delayHide={100}
|
|
||||||
disable={!appLayout.mainPanelReduced || isMobile || isCoarse}
|
|
||||||
className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg after:!border-r-light text-left !text-black"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{props.extra}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,14 @@
|
|||||||
|
import { MouseEventHandler } from "react";
|
||||||
|
|
||||||
type ChipProps = {
|
type ChipProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
"data-tip"?: string;
|
|
||||||
"data-for"?: string;
|
|
||||||
"data-html"?: boolean;
|
|
||||||
"data-multiline"?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Chip(props: ChipProps): JSX.Element {
|
export default function Chip(props: ChipProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`grid place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,border-color] ${
|
className={`grid relative place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,_border-color] hover:opacity-100 ${props.className}`}
|
||||||
props.className
|
|
||||||
} ${
|
|
||||||
props["data-tip"] &&
|
|
||||||
"hover:text-dark hover:border-dark hover:opacity-100"
|
|
||||||
}`}
|
|
||||||
data-tip={props["data-tip"]}
|
|
||||||
data-for={props["data-for"]}
|
|
||||||
data-html={props["data-html"]}
|
|
||||||
data-multiline={props["data-multiline"]}
|
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
import Chip from "components/Chip";
|
import Chip from "components/Chip";
|
||||||
|
import ToolTip from "components/ToolTip";
|
||||||
import {
|
import {
|
||||||
Enum_Componenttranslationschronologyitem_Status,
|
Enum_Componenttranslationschronologyitem_Status,
|
||||||
GetChronologyItemsQuery,
|
GetChronologyItemsQuery,
|
||||||
|
GetWebsiteInterfaceQuery,
|
||||||
} from "graphql/operations-types";
|
} from "graphql/operations-types";
|
||||||
|
import { getStatusDescription } from "queries/helpers";
|
||||||
|
|
||||||
export type ChronologyItemComponentProps = {
|
export type ChronologyItemComponentProps = {
|
||||||
item: GetChronologyItemsQuery["chronologyItems"]["data"][number];
|
item: GetChronologyItemsQuery["chronologyItems"]["data"][number];
|
||||||
displayYear: boolean;
|
displayYear: boolean;
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ChronologyItemComponent(
|
export default function ChronologyItemComponent(
|
||||||
props: ChronologyItemComponentProps
|
props: ChronologyItemComponentProps
|
||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
|
const { langui } = props;
|
||||||
|
|
||||||
function generateAnchor(year: number, month: number, day: number): string {
|
function generateAnchor(year: number, month: number, day: number): string {
|
||||||
let result: string = "";
|
let result: string = "";
|
||||||
result += year;
|
result += year;
|
||||||
@ -85,23 +91,12 @@ export default function ChronologyItemComponent(
|
|||||||
<div className="place-items-start place-content-start grid grid-flow-col gap-2">
|
<div className="place-items-start place-content-start grid grid-flow-col gap-2">
|
||||||
{translation.status !==
|
{translation.status !==
|
||||||
Enum_Componenttranslationschronologyitem_Status.Done && (
|
Enum_Componenttranslationschronologyitem_Status.Done && (
|
||||||
<Chip
|
<ToolTip
|
||||||
data-tip={
|
content={getStatusDescription(translation.status, langui)}
|
||||||
translation.status ===
|
maxWidth={"20rem"}
|
||||||
Enum_Componenttranslationschronologyitem_Status.Incomplete
|
|
||||||
? "This entry is only partially translated/transcribed."
|
|
||||||
: translation.status ===
|
|
||||||
Enum_Componenttranslationschronologyitem_Status.Draft
|
|
||||||
? "This entry is just a draft. It usually means that this is a work-in-progress. Translation/transcription might be poor and/or computer-generated."
|
|
||||||
: translation.status ===
|
|
||||||
Enum_Componenttranslationschronologyitem_Status.Review
|
|
||||||
? "This entry has not yet being proofread. The content should still be accurate."
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
data-for={"ChronologyTooltip"}
|
|
||||||
>
|
>
|
||||||
{translation.status}
|
<Chip>{translation.status}</Chip>
|
||||||
</Chip>
|
</ToolTip>
|
||||||
)}
|
)}
|
||||||
{translation.title ? <h3>{translation.title}</h3> : ""}
|
{translation.title ? <h3>{translation.title}</h3> : ""}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import ChronologyItemComponent from "components/Chronology/ChronologyItemComponent";
|
import ChronologyItemComponent from "components/Chronology/ChronologyItemComponent";
|
||||||
import { GetChronologyItemsQuery } from "graphql/operations-types";
|
import {
|
||||||
|
GetChronologyItemsQuery,
|
||||||
|
GetWebsiteInterfaceQuery,
|
||||||
|
} from "graphql/operations-types";
|
||||||
|
|
||||||
type ChronologyYearComponentProps = {
|
type ChronologyYearComponentProps = {
|
||||||
year: number;
|
year: number;
|
||||||
items: GetChronologyItemsQuery["chronologyItems"]["data"][number][];
|
items: GetChronologyItemsQuery["chronologyItems"]["data"][number][];
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ChronologyYearComponent(
|
export default function ChronologyYearComponent(
|
||||||
props: ChronologyYearComponentProps
|
props: ChronologyYearComponentProps
|
||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
|
const { langui } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="target:bg-mid rounded-2xl target:py-4 target:my-4"
|
className="target:bg-mid rounded-2xl target:py-4 target:my-4"
|
||||||
@ -19,6 +25,7 @@ export default function ChronologyYearComponent(
|
|||||||
key={index}
|
key={index}
|
||||||
item={item}
|
item={item}
|
||||||
displayYear={index === 0}
|
displayYear={index === 0}
|
||||||
|
langui={langui}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,7 +55,7 @@ export default function LibraryItemsPreview(
|
|||||||
<h3 className="mobile:text-xs leading-3">{item.subtitle}</h3>
|
<h3 className="mobile:text-xs leading-3">{item.subtitle}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full grid grid-flow-col gap-1 overflow-x-scroll webkit-scrollbar:w-0 [scrollbar-width:none] place-content-start">
|
<div className="w-full grid grid-flow-col gap-1 overflow-x-scroll webkit-scrollbar:h-0 [scrollbar-width:none] place-content-start">
|
||||||
{item.categories.data.map((category) => (
|
{item.categories.data.map((category) => (
|
||||||
<Chip key={category.id} className="text-sm">
|
<Chip key={category.id} className="text-sm">
|
||||||
{category.attributes.short}
|
{category.attributes.short}
|
||||||
|
@ -21,6 +21,38 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
options={{
|
options={{
|
||||||
slugify: slugify,
|
slugify: slugify,
|
||||||
overrides: {
|
overrides: {
|
||||||
|
h2: {
|
||||||
|
component: (props: {
|
||||||
|
id: string;
|
||||||
|
style: React.CSSProperties;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<h2
|
||||||
|
id={props.id}
|
||||||
|
className="flex flex-row place-items-center place-content-center gap-3 hover:[--anchor-opacity:100] [--anchor-opacity:0]"
|
||||||
|
style={props.style}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
<abbr title="Copy anchor link">
|
||||||
|
<span
|
||||||
|
className="material-icons opacity-[var(--anchor-opacity)] transition-all hover:text-dark cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(
|
||||||
|
process.env.NEXT_PUBLIC_URL_SELF +
|
||||||
|
window.location.pathname +
|
||||||
|
"#" +
|
||||||
|
props.id
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
link
|
||||||
|
</span>
|
||||||
|
</abbr>
|
||||||
|
</h2>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
Sep: {
|
Sep: {
|
||||||
component: () => {
|
component: () => {
|
||||||
return <div className="my-24"></div>;
|
return <div className="my-24"></div>;
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
|
import { NextRouter } from "next/router";
|
||||||
import { slugify } from "queries/helpers";
|
import { slugify } from "queries/helpers";
|
||||||
import { preprocessMarkDawn } from "./Markdawn";
|
import { preprocessMarkDawn } from "./Markdawn";
|
||||||
|
|
||||||
type TOCProps = {
|
type TOCProps = {
|
||||||
text: string;
|
text: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
router: NextRouter;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TOC(props: TOCProps): JSX.Element {
|
export default function TOC(props: TOCProps): JSX.Element {
|
||||||
const toc = getTocFromMarkdawn(preprocessMarkDawn(props.text), props.title);
|
const { router, text, title } = props;
|
||||||
|
const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-xl">Table of content</h3>
|
<h3 className="text-xl">Table of content</h3>
|
||||||
<ol className="text-left">
|
<ol className="text-left">
|
||||||
<li className="my-2 overflow-x-hidden w-full text-ellipsis whitespace-nowrap">
|
<li className="my-2 overflow-x-hidden w-full text-ellipsis whitespace-nowrap">
|
||||||
<a className="" href={`#${toc.slug}`}>
|
<a className="" onClick={() => router.replace(`#${toc.slug}`)}>
|
||||||
{<abbr title={toc.title}>{toc.title}</abbr>}
|
{<abbr title={toc.title}>{toc.title}</abbr>}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -25,7 +28,7 @@ export default function TOC(props: TOCProps): JSX.Element {
|
|||||||
className="my-2 overflow-x-hidden w-full text-ellipsis whitespace-nowrap"
|
className="my-2 overflow-x-hidden w-full text-ellipsis whitespace-nowrap"
|
||||||
>
|
>
|
||||||
<span className="text-dark">{`${h2Index + 1}. `}</span>
|
<span className="text-dark">{`${h2Index + 1}. `}</span>
|
||||||
<a href={`#${h2.slug}`}>
|
<a onClick={() => router.replace(`#${h2.slug}`)}>
|
||||||
{<abbr title={h2.title}>{h2.title}</abbr>}
|
{<abbr title={h2.title}>{h2.title}</abbr>}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -38,7 +41,7 @@ export default function TOC(props: TOCProps): JSX.Element {
|
|||||||
<span className="text-dark">{`${h2Index + 1}.${
|
<span className="text-dark">{`${h2Index + 1}.${
|
||||||
h3Index + 1
|
h3Index + 1
|
||||||
}. `}</span>
|
}. `}</span>
|
||||||
<a href={`#${h3.slug}`}>
|
<a onClick={() => router.replace(`#${h3.slug}`)}>
|
||||||
{<abbr title={h3.title}>{h3.title}</abbr>}
|
{<abbr title={h3.title}>{h3.title}</abbr>}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { MouseEventHandler } from "react";
|
import { MouseEventHandler } from "react";
|
||||||
import ReactDOMServer from "react-dom/server";
|
import ToolTip from "components/ToolTip";
|
||||||
|
|
||||||
type NavOptionProps = {
|
type NavOptionProps = {
|
||||||
url: string;
|
url: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
tooltipId?: string;
|
|
||||||
border?: boolean;
|
border?: boolean;
|
||||||
reduced?: boolean;
|
reduced?: boolean;
|
||||||
onClick?: MouseEventHandler<HTMLDivElement>;
|
onClick?: MouseEventHandler<HTMLDivElement>;
|
||||||
@ -25,35 +24,38 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
|
|||||||
} ${isActive ? divActive : ""}`;
|
} ${isActive ? divActive : ""}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={props.url} passHref>
|
<ToolTip
|
||||||
<div
|
content={
|
||||||
onClick={props.onClick}
|
<div>
|
||||||
data-html
|
<h3 className="text-2xl">{props.title}</h3>
|
||||||
data-multiline
|
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
|
||||||
data-tip={ReactDOMServer.renderToStaticMarkup(
|
</div>
|
||||||
<div className="px-4 py-3">
|
}
|
||||||
<h3 className="text-2xl">{props.title}</h3>
|
placement="right"
|
||||||
{props.subtitle && (
|
className="text-left"
|
||||||
<p className="max-w-[10rem]">{props.subtitle}</p>
|
disabled={!props.reduced}
|
||||||
)}
|
>
|
||||||
</div>
|
<Link href={props.url} passHref>
|
||||||
)}
|
<div
|
||||||
data-for={props.tooltipId}
|
onClick={props.onClick}
|
||||||
className={`grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
|
className={`relative grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
|
||||||
props.icon ? "text-left" : "text-center"
|
props.icon ? "text-left" : "text-center"
|
||||||
} ${divCommon}`}
|
} ${divCommon}`}
|
||||||
>
|
>
|
||||||
{props.icon && (
|
{props.icon && (
|
||||||
<span className="material-icons mt-[.1em]">{props.icon}</span>
|
<span className="material-icons mt-[.1em]">{props.icon}</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!props.reduced && (
|
{!props.reduced && (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-2xl">{props.title}</h3>
|
<h3 className="text-2xl">{props.title}</h3>
|
||||||
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
|
{props.subtitle && (
|
||||||
</div>
|
<p className="col-start-2">{props.subtitle}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</ToolTip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
|||||||
import Markdown from "markdown-to-jsx";
|
import Markdown from "markdown-to-jsx";
|
||||||
import { useMediaDesktop } from "hooks/useMediaQuery";
|
import { useMediaDesktop } from "hooks/useMediaQuery";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
|
import ToolTip from "components/ToolTip";
|
||||||
|
|
||||||
type MainPanelProps = {
|
type MainPanelProps = {
|
||||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
@ -24,6 +25,20 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
appLayout.mainPanelReduced && isDesktop && "px-4"
|
appLayout.mainPanelReduced && isDesktop && "px-4"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
{/* Reduce/expand main menu */}
|
||||||
|
<div
|
||||||
|
className={`mobile:hidden top-1/2 fixed ${
|
||||||
|
appLayout.mainPanelReduced ? "left-[4.65rem]" : "left-[18.65rem]"
|
||||||
|
}`}
|
||||||
|
onClick={() =>
|
||||||
|
appLayout.setMainPanelReduced(!appLayout.mainPanelReduced)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button className="material-icons bg-light !px-2">
|
||||||
|
{appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<Link href="/" passHref>
|
<Link href="/" passHref>
|
||||||
@ -48,49 +63,74 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
: "flex-row"
|
: "flex-row"
|
||||||
} flex-wrap gap-2`}
|
} flex-wrap gap-2`}
|
||||||
>
|
>
|
||||||
<Button
|
<ToolTip
|
||||||
className={
|
content={<h3 className="text-2xl">{"Open settings"}</h3>}
|
||||||
appLayout.mainPanelReduced && isDesktop ? "" : "!py-0.5 !px-2.5"
|
placement="right"
|
||||||
}
|
className="text-left"
|
||||||
onClick={() => {
|
disabled={!appLayout.mainPanelReduced}
|
||||||
appLayout.setConfigPanelOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<span
|
|
||||||
className={`material-icons ${
|
|
||||||
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
|
|
||||||
} `}
|
|
||||||
>
|
|
||||||
settings
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{router.locale && (
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => appLayout.setLanguagePanelOpen(true)}
|
|
||||||
className={
|
className={
|
||||||
appLayout.mainPanelReduced && isDesktop
|
appLayout.mainPanelReduced && isDesktop
|
||||||
? ""
|
? ""
|
||||||
: "!py-0.5 !px-2.5 !text-sm"
|
: "!py-0.5 !px-2.5"
|
||||||
}
|
}
|
||||||
|
onClick={() => {
|
||||||
|
appLayout.setConfigPanelOpen(true);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{router.locale.toUpperCase()}
|
<span
|
||||||
|
className={`material-icons ${
|
||||||
|
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
|
||||||
|
} `}
|
||||||
|
>
|
||||||
|
settings
|
||||||
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
</ToolTip>
|
||||||
|
|
||||||
|
{router.locale && (
|
||||||
|
<ToolTip
|
||||||
|
content={<h3 className="text-2xl">{"Change language"}</h3>}
|
||||||
|
placement="right"
|
||||||
|
className="text-left"
|
||||||
|
disabled={!appLayout.mainPanelReduced}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
onClick={() => appLayout.setLanguagePanelOpen(true)}
|
||||||
|
className={
|
||||||
|
appLayout.mainPanelReduced && isDesktop
|
||||||
|
? ""
|
||||||
|
: "!py-0.5 !px-2.5 !text-sm"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{router.locale.toUpperCase()}
|
||||||
|
</Button>
|
||||||
|
</ToolTip>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
<ToolTip
|
||||||
className={
|
content={<h3 className="text-2xl">{"Open search"}</h3>}
|
||||||
appLayout.mainPanelReduced && isDesktop ? "" : "!py-0.5 !px-2.5"
|
placement="right"
|
||||||
}
|
className="text-left"
|
||||||
|
disabled={!appLayout.mainPanelReduced}
|
||||||
>
|
>
|
||||||
<span
|
<Button
|
||||||
className={`material-icons ${
|
className={
|
||||||
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
|
appLayout.mainPanelReduced && isDesktop
|
||||||
} `}
|
? ""
|
||||||
|
: "!py-0.5 !px-2.5"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
search
|
<span
|
||||||
</span>
|
className={`material-icons ${
|
||||||
</Button>
|
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
|
||||||
|
} `}
|
||||||
|
>
|
||||||
|
search
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -102,7 +142,6 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
icon="library_books"
|
icon="library_books"
|
||||||
title={langui.library}
|
title={langui.library}
|
||||||
subtitle={langui.library_short_description}
|
subtitle={langui.library_short_description}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -112,7 +151,6 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
icon="workspaces"
|
icon="workspaces"
|
||||||
title={langui.contents}
|
title={langui.contents}
|
||||||
subtitle={langui.contents_short_description}
|
subtitle={langui.contents_short_description}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -124,7 +162,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
icon="travel_explore"
|
icon="travel_explore"
|
||||||
title={langui.wiki}
|
title={langui.wiki}
|
||||||
subtitle={langui.wiki_short_description}
|
subtitle={langui.wiki_short_description}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -134,7 +172,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
icon="watch_later"
|
icon="watch_later"
|
||||||
title={langui.chronicles}
|
title={langui.chronicles}
|
||||||
subtitle={langui.chronicles_short_description}
|
subtitle={langui.chronicles_short_description}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -147,7 +185,6 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
url="/news"
|
url="/news"
|
||||||
icon="feed"
|
icon="feed"
|
||||||
title={langui.news}
|
title={langui.news}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -156,7 +193,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
url="/merch"
|
url="/merch"
|
||||||
icon="store"
|
icon="store"
|
||||||
title={langui.merch}
|
title={langui.merch}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -167,7 +204,6 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
url="/gallery"
|
url="/gallery"
|
||||||
icon="collections"
|
icon="collections"
|
||||||
title={langui.gallery}
|
title={langui.gallery}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -178,7 +214,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
url="/archives"
|
url="/archives"
|
||||||
icon="inventory"
|
icon="inventory"
|
||||||
title={langui.archives}
|
title={langui.archives}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
@ -190,7 +226,6 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
|||||||
url="/about-us"
|
url="/about-us"
|
||||||
icon="info"
|
icon="info"
|
||||||
title={langui.about_us}
|
title={langui.about_us}
|
||||||
tooltipId="MainPanelTooltip"
|
|
||||||
reduced={appLayout.mainPanelReduced && isDesktop}
|
reduced={appLayout.mainPanelReduced && isDesktop}
|
||||||
onClick={() => appLayout.setMainPanelOpen(false)}
|
onClick={() => appLayout.setMainPanelOpen(false)}
|
||||||
/>
|
/>
|
||||||
|
@ -4,7 +4,7 @@ type SubPanelProps = {
|
|||||||
|
|
||||||
export default function SubPanel(props: SubPanelProps): JSX.Element {
|
export default function SubPanel(props: SubPanelProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col p-8 gap-y-2 justify-items-center text-center mobile:h-full">
|
<div className="grid pt-10 pb-20 px-6 desktop:py-8 desktop:px-10 gap-y-2 text-center">
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,9 @@ export default function Popup(props: PopupProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed inset-0 z-50 grid place-content-center transition-[backdrop-filter] duration-500 ${
|
className={`fixed inset-0 z-50 grid place-content-center transition-[backdrop-filter] duration-500 ${
|
||||||
props.state ? "[backdrop-filter:blur(2px)]" : "pointer-events-none touch-none"
|
props.state
|
||||||
|
? "[backdrop-filter:blur(2px)]"
|
||||||
|
: "pointer-events-none touch-none"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
GetWebsiteInterfaceQuery,
|
GetWebsiteInterfaceQuery,
|
||||||
} from "graphql/operations-types";
|
} from "graphql/operations-types";
|
||||||
import Img, { ImageQuality } from "./Img";
|
import Img, { ImageQuality } from "./Img";
|
||||||
import ReactDOMServer from "react-dom/server";
|
import ToolTip from "./ToolTip";
|
||||||
|
|
||||||
type RecorderChipProps = {
|
type RecorderChipProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -15,10 +15,10 @@ type RecorderChipProps = {
|
|||||||
export default function RecorderChip(props: RecorderChipProps): JSX.Element {
|
export default function RecorderChip(props: RecorderChipProps): JSX.Element {
|
||||||
const recorder = props.recorder;
|
const recorder = props.recorder;
|
||||||
const langui = props.langui;
|
const langui = props.langui;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chip
|
<ToolTip
|
||||||
key={recorder.id}
|
content={
|
||||||
data-tip={ReactDOMServer.renderToStaticMarkup(
|
|
||||||
<div className="p-2 py-5 grid gap-2">
|
<div className="p-2 py-5 grid gap-2">
|
||||||
<div className="grid grid-flow-col gap-2 place-items-center place-content-start">
|
<div className="grid grid-flow-col gap-2 place-items-center place-content-start">
|
||||||
{recorder.attributes.avatar.data && (
|
{recorder.attributes.avatar.data && (
|
||||||
@ -52,14 +52,14 @@ export default function RecorderChip(props: RecorderChipProps): JSX.Element {
|
|||||||
recorder.attributes.bio[0].bio}
|
recorder.attributes.bio[0].bio}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
}
|
||||||
data-for={"RecordersTooltip"}
|
placement="top"
|
||||||
data-multiline
|
|
||||||
data-html
|
|
||||||
>
|
>
|
||||||
{recorder.attributes.anonymize
|
<Chip key={recorder.id}>
|
||||||
? `Recorder#${recorder.attributes.anonymous_code}`
|
{recorder.attributes.anonymize
|
||||||
: recorder.attributes.username}
|
? `Recorder#${recorder.attributes.anonymous_code}`
|
||||||
</Chip>
|
: recorder.attributes.username}
|
||||||
|
</Chip>
|
||||||
|
</ToolTip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
19
src/components/ToolTip.tsx
Normal file
19
src/components/ToolTip.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import Tippy, { TippyProps } from "@tippyjs/react";
|
||||||
|
import "tippy.js/animations/scale-subtle.css";
|
||||||
|
|
||||||
|
interface ToolTipProps extends TippyProps {}
|
||||||
|
|
||||||
|
export default function ToolTip(props: ToolTipProps): JSX.Element {
|
||||||
|
let newProps = { ...props };
|
||||||
|
|
||||||
|
// Set defaults
|
||||||
|
if (newProps.delay === undefined) newProps.delay = [150, 0];
|
||||||
|
if (newProps.interactive === undefined) newProps.interactive = true;
|
||||||
|
if (newProps.animation === undefined) newProps.animation = "scale-subtle";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tippy {...newProps}>
|
||||||
|
<div>{props.children}</div>
|
||||||
|
</Tippy>
|
||||||
|
);
|
||||||
|
}
|
@ -2,7 +2,7 @@ import type { AppProps } from "next/app";
|
|||||||
import "tailwind.css";
|
import "tailwind.css";
|
||||||
import "@fontsource/zen-maru-gothic/500.css";
|
import "@fontsource/zen-maru-gothic/500.css";
|
||||||
import "@fontsource/vollkorn/700.css";
|
import "@fontsource/vollkorn/700.css";
|
||||||
import "@fontsource/opendyslexic/400.css"
|
import "@fontsource/opendyslexic/400.css";
|
||||||
import "@fontsource/material-icons";
|
import "@fontsource/material-icons";
|
||||||
|
|
||||||
import { AppContextProvider } from "contexts/AppLayoutContext";
|
import { AppContextProvider } from "contexts/AppLayoutContext";
|
||||||
|
@ -16,7 +16,6 @@ class MyDocument extends Document {
|
|||||||
return (
|
return (
|
||||||
<Html>
|
<Html>
|
||||||
<Head>
|
<Head>
|
||||||
|
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
sizes="180x180"
|
sizes="180x180"
|
||||||
|
@ -14,6 +14,7 @@ import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
|||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import Markdawn from "components/Markdown/Markdawn";
|
import Markdawn from "components/Markdown/Markdawn";
|
||||||
import {
|
import {
|
||||||
|
getStatusDescription,
|
||||||
prettyinlineTitle,
|
prettyinlineTitle,
|
||||||
prettyLanguage,
|
prettyLanguage,
|
||||||
prettySlug,
|
prettySlug,
|
||||||
@ -23,10 +24,10 @@ import {
|
|||||||
import Button from "components/Button";
|
import Button from "components/Button";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Chip from "components/Chip";
|
import Chip from "components/Chip";
|
||||||
import ReactTooltip from "react-tooltip";
|
|
||||||
import RecorderChip from "components/RecorderChip";
|
import RecorderChip from "components/RecorderChip";
|
||||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||||
import TOC from "components/Markdown/TOC";
|
import TOC from "components/Markdown/TOC";
|
||||||
|
import ToolTip from "components/ToolTip";
|
||||||
|
|
||||||
interface ContentReadProps extends AppStaticProps {
|
interface ContentReadProps extends AppStaticProps {
|
||||||
content: GetContentTextQuery["contents"]["data"][number]["attributes"];
|
content: GetContentTextQuery["contents"]["data"][number]["attributes"];
|
||||||
@ -35,7 +36,7 @@ interface ContentReadProps extends AppStaticProps {
|
|||||||
|
|
||||||
export default function ContentRead(props: ContentReadProps): JSX.Element {
|
export default function ContentRead(props: ContentReadProps): JSX.Element {
|
||||||
useTesting(props);
|
useTesting(props);
|
||||||
const { langui, content } = props;
|
const { langui, content, languages } = props;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
@ -68,7 +69,8 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
{prettyLanguage(
|
{prettyLanguage(
|
||||||
content.text_set[0].source_language.data.attributes.code
|
content.text_set[0].source_language.data.attributes.code,
|
||||||
|
languages
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -77,23 +79,12 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
<div className="grid grid-flow-col place-items-center place-content-center gap-2">
|
<div className="grid grid-flow-col place-items-center place-content-center gap-2">
|
||||||
<p className="font-headers">{langui.status}:</p>
|
<p className="font-headers">{langui.status}:</p>
|
||||||
|
|
||||||
<Chip
|
<ToolTip
|
||||||
data-tip={
|
content={getStatusDescription(content.text_set[0].status, langui)}
|
||||||
content.text_set[0].status ===
|
maxWidth={"20rem"}
|
||||||
Enum_Componentsetstextset_Status.Incomplete
|
|
||||||
? langui.status_incomplete
|
|
||||||
: content.text_set[0].status ===
|
|
||||||
Enum_Componentsetstextset_Status.Draft
|
|
||||||
? langui.status_draft
|
|
||||||
: content.text_set[0].status ===
|
|
||||||
Enum_Componentsetstextset_Status.Review
|
|
||||||
? langui.status_review
|
|
||||||
: langui.status_done
|
|
||||||
}
|
|
||||||
data-for={"StatusTooltip"}
|
|
||||||
>
|
>
|
||||||
{content.text_set[0].status}
|
<Chip>{content.text_set[0].status}</Chip>
|
||||||
</Chip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{content.text_set[0].transcribers.data.length > 0 && (
|
{content.text_set[0].transcribers.data.length > 0 && (
|
||||||
@ -148,6 +139,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
<TOC
|
<TOC
|
||||||
text={content.text_set[0].text}
|
text={content.text_set[0].text}
|
||||||
|
router={router}
|
||||||
title={
|
title={
|
||||||
content.titles.length > 0
|
content.titles.length > 0
|
||||||
? prettyinlineTitle(
|
? prettyinlineTitle(
|
||||||
@ -183,32 +175,6 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
);
|
);
|
||||||
|
|
||||||
const extra = (
|
|
||||||
<>
|
|
||||||
<ReactTooltip
|
|
||||||
id="StatusTooltip"
|
|
||||||
place="top"
|
|
||||||
type="light"
|
|
||||||
effect="solid"
|
|
||||||
delayShow={50}
|
|
||||||
clickable={true}
|
|
||||||
className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg desktop:after:!border-t-light text-left !text-black max-w-xs"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ReactTooltip
|
|
||||||
id="RecordersTooltip"
|
|
||||||
place="top"
|
|
||||||
type="light"
|
|
||||||
effect="solid"
|
|
||||||
delayShow={100}
|
|
||||||
delayUpdate={100}
|
|
||||||
delayHide={100}
|
|
||||||
clickable={true}
|
|
||||||
className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg desktop:after:!border-t-light text-left !text-black max-w-[22rem]"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle="Contents"
|
navTitle="Contents"
|
||||||
@ -224,7 +190,6 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
thumbnail={content.thumbnail.data?.attributes}
|
thumbnail={content.thumbnail.data?.attributes}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
extra={extra}
|
|
||||||
description={`${langui.type}: ${
|
description={`${langui.type}: ${
|
||||||
content.type.data.attributes.titles.length > 0
|
content.type.data.attributes.titles.length > 0
|
||||||
? content.type.data.attributes.titles[0].title
|
? content.type.data.attributes.titles[0].title
|
||||||
|
@ -15,6 +15,13 @@ export default function Home(props: HomeProps): JSX.Element {
|
|||||||
const { post } = props;
|
const { post } = props;
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
|
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
|
||||||
|
<div className="[mask:url('/icons/accords.svg')] [mask-size:contain] [mask-repeat:no-repeat] [mask-position:center] w-32 aspect-square mobile:w-[50vw] bg-black" />
|
||||||
|
<h1 className="text-5xl mb-0">Accord’s Library</h1>
|
||||||
|
<h2 className="text-xl -mt-5">
|
||||||
|
Discover • Analyse • Translate • Archive
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
{post.translations.length > 0 && (
|
{post.translations.length > 0 && (
|
||||||
<Markdawn text={post.translations[0].body} />
|
<Markdawn text={post.translations[0].body} />
|
||||||
)}
|
)}
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
} from "queries/helpers";
|
} from "queries/helpers";
|
||||||
import InsetBox from "components/InsetBox";
|
import InsetBox from "components/InsetBox";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import ReactTooltip from "react-tooltip";
|
|
||||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||||
|
|
||||||
interface ChronologyProps extends AppStaticProps {
|
interface ChronologyProps extends AppStaticProps {
|
||||||
@ -26,7 +25,7 @@ interface ChronologyProps extends AppStaticProps {
|
|||||||
|
|
||||||
export default function Chronology(props: ChronologyProps): JSX.Element {
|
export default function Chronology(props: ChronologyProps): JSX.Element {
|
||||||
useTesting(props);
|
useTesting(props);
|
||||||
const { chronologyItems, chronologyEras } = props;
|
const { chronologyItems, chronologyEras, langui } = props;
|
||||||
|
|
||||||
// Group by year the Chronology items
|
// Group by year the Chronology items
|
||||||
let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][][] =
|
let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][][] =
|
||||||
@ -103,20 +102,11 @@ export default function Chronology(props: ChronologyProps): JSX.Element {
|
|||||||
key={`${eraIndex}-${index}`}
|
key={`${eraIndex}-${index}`}
|
||||||
year={items[0].attributes.year}
|
year={items[0].attributes.year}
|
||||||
items={items}
|
items={items}
|
||||||
|
langui={langui}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<ReactTooltip
|
|
||||||
id="ChronologyTooltip"
|
|
||||||
place="top"
|
|
||||||
type="light"
|
|
||||||
effect="solid"
|
|
||||||
delayShow={50}
|
|
||||||
clickable={true}
|
|
||||||
className="drop-shadow-shade-xl !opacity-100 mobile:after:!border-r-light !bg-light !rounded-lg desktop:after:!border-t-light text-left !text-black max-w-xs"
|
|
||||||
/>
|
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ import {
|
|||||||
ImageQuality,
|
ImageQuality,
|
||||||
} from "components/Img";
|
} from "components/Img";
|
||||||
import {
|
import {
|
||||||
|
Enum_Componentsetstextset_Status,
|
||||||
GetCurrenciesQuery,
|
GetCurrenciesQuery,
|
||||||
|
GetLanguagesQuery,
|
||||||
GetLibraryItemQuery,
|
GetLibraryItemQuery,
|
||||||
GetLibraryItemsPreviewQuery,
|
GetLibraryItemsPreviewQuery,
|
||||||
GetWebsiteInterfaceQuery,
|
GetWebsiteInterfaceQuery,
|
||||||
@ -138,23 +140,16 @@ export function prettyItemSubType(metadata: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function prettyLanguage(code: string): string {
|
export function prettyLanguage(
|
||||||
switch (code) {
|
code: string,
|
||||||
case "en":
|
languages: GetLanguagesQuery["languages"]["data"]
|
||||||
return "English";
|
): string {
|
||||||
case "es":
|
let result = code;
|
||||||
return "Español";
|
languages.forEach((language) => {
|
||||||
case "fr":
|
if (language.attributes.code === code)
|
||||||
return "Français";
|
result = language.attributes.localized_name;
|
||||||
case "ja":
|
});
|
||||||
return "日本語";
|
return result;
|
||||||
case "en":
|
|
||||||
return "English";
|
|
||||||
case "xx":
|
|
||||||
return "██";
|
|
||||||
default:
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function prettyTestWarning(
|
export function prettyTestWarning(
|
||||||
@ -257,6 +252,28 @@ export function sortContent(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getStatusDescription(
|
||||||
|
status: string,
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]
|
||||||
|
): string {
|
||||||
|
switch (status) {
|
||||||
|
case Enum_Componentsetstextset_Status.Incomplete:
|
||||||
|
return langui.status_incomplete;
|
||||||
|
|
||||||
|
case Enum_Componentsetstextset_Status.Draft:
|
||||||
|
return langui.status_draft;
|
||||||
|
|
||||||
|
case Enum_Componentsetstextset_Status.Review:
|
||||||
|
return langui.status_review;
|
||||||
|
|
||||||
|
case Enum_Componentsetstextset_Status.Done:
|
||||||
|
return langui.status_done;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function slugify(str: string): string {
|
export function slugify(str: string): string {
|
||||||
return str
|
return str
|
||||||
.replace(/[ÀÁÂÃÄÅàáâãä忯]/g, "a")
|
.replace(/[ÀÁÂÃÄÅàáâãä忯]/g, "a")
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark;
|
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark cursor-pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
*::selection {
|
*::selection {
|
||||||
@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
mark {
|
mark {
|
||||||
@apply bg-mid px-2
|
@apply bg-mid px-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SCROLLBARS STYLING */
|
/* SCROLLBARS STYLING */
|
||||||
@ -142,3 +142,66 @@
|
|||||||
@apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm];
|
@apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tippy-box[data-animation="fade"][data-state="hidden"] {
|
||||||
|
@apply opacity-0;
|
||||||
|
}
|
||||||
|
[data-tippy-root] {
|
||||||
|
max-width: calc(100vw - 10px);
|
||||||
|
}
|
||||||
|
.tippy-box {
|
||||||
|
@apply relative bg-light drop-shadow-shade-xl rounded-lg transition-[transform,_visibility,_opacity];
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="top"] > .tippy-arrow {
|
||||||
|
@apply bottom-0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="top"] > .tippy-arrow:before {
|
||||||
|
bottom: -7px;
|
||||||
|
left: 0;
|
||||||
|
border-width: 8px 8px 0;
|
||||||
|
border-top-color: initial;
|
||||||
|
transform-origin: center top;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="bottom"] > .tippy-arrow {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="bottom"] > .tippy-arrow:before {
|
||||||
|
top: -7px;
|
||||||
|
left: 0;
|
||||||
|
border-width: 0 8px 8px;
|
||||||
|
border-bottom-color: initial;
|
||||||
|
transform-origin: center bottom;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="left"] > .tippy-arrow {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="left"] > .tippy-arrow:before {
|
||||||
|
border-width: 8px 0 8px 8px;
|
||||||
|
border-left-color: initial;
|
||||||
|
right: -7px;
|
||||||
|
transform-origin: center left;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="right"] > .tippy-arrow {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="right"] > .tippy-arrow:before {
|
||||||
|
left: -7px;
|
||||||
|
border-width: 8px 8px 8px 0;
|
||||||
|
border-right-color: initial;
|
||||||
|
transform-origin: center right;
|
||||||
|
}
|
||||||
|
.tippy-box[data-inertia][data-state="visible"] {
|
||||||
|
transition-timing-function: cubic-bezier(0.54, 1.5, 0.38, 1.11);
|
||||||
|
}
|
||||||
|
.tippy-arrow {
|
||||||
|
@apply h-4 w-4 text-light;
|
||||||
|
}
|
||||||
|
.tippy-arrow:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
.tippy-content {
|
||||||
|
@apply relative px-6 py-4 z-10;
|
||||||
|
}
|
||||||
|
@ -72,7 +72,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|
||||||
plugin(function ({ addUtilities }) {
|
plugin(function ({ addUtilities }) {
|
||||||
addUtilities({
|
addUtilities({
|
||||||
".set-theme-light": {
|
".set-theme-light": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user