Applied more lint rules and fixed the code accordingly
This commit is contained in:
		
							parent
							
								
									38543ae3dd
								
							
						
					
					
						commit
						4a123a0236
					
				
							
								
								
									
										2
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| *.js | ||||
| *.ts | ||||
							
								
								
									
										214
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,214 @@ | ||||
| module.exports = { | ||||
|   parser: "@typescript-eslint/parser", | ||||
|   parserOptions: { | ||||
|     project: `./tsconfig.json`, | ||||
|   }, | ||||
|   plugins: ["@typescript-eslint"], | ||||
|   extends: [ | ||||
|     "eslint:recommended", | ||||
|     "plugin:@typescript-eslint/recommended", | ||||
|     "next/core-web-vitals", | ||||
|   ], | ||||
|   rules: { | ||||
|     /* POSSIBLES PROBLEMS */ | ||||
| 
 | ||||
|     // "array-callback-return": "error",
 | ||||
|     "no-await-in-loop": "error", | ||||
|     "no-constructor-return": "error", | ||||
|     "no-promise-executor-return": "error", | ||||
|     "no-self-compare": "error", | ||||
|     "no-template-curly-in-string": "error", | ||||
|     "no-unmodified-loop-condition": "error", | ||||
|     "no-unreachable-loop": "error", | ||||
|     "no-unused-private-class-members": "error", | ||||
|     // "no-use-before-define": "error",
 | ||||
|     "require-atomic-updates": "error", | ||||
| 
 | ||||
|     /* SUGGESTIONS */ | ||||
| 
 | ||||
|     "accessor-pairs": "warn", | ||||
|     "arrow-body-style": "warn", | ||||
|     "block-scoped-var": "warn", | ||||
|     // camelcase: "warn",
 | ||||
|     // "capitalized-comments": "warn",
 | ||||
|     // "class-methods-use-this": "warn",
 | ||||
|     // complexity: "warn",
 | ||||
|     "consistent-return": "warn", | ||||
|     "consistent-this": "warn", | ||||
|     // curly: "warn",
 | ||||
|     "default-case": "warn", | ||||
|     "default-case-last": "warn", | ||||
|     eqeqeq: "error", | ||||
|     "func-name-matching": "warn", | ||||
|     "func-names": "warn", | ||||
|     "func-style": ["warn", "declaration"], | ||||
|     "grouped-accessor-pairs": "warn", | ||||
|     "guard-for-in": "warn", | ||||
|     "id-denylist": ["error", "data", "err", "e", "cb", "callback", "i"], | ||||
|     // "id-length": "warn",
 | ||||
|     "id-match": "warn", | ||||
|     "max-classes-per-file": ["error", 1], | ||||
|     // "max-depth": ["warn", 4],
 | ||||
|     // "max-lines": "warn",
 | ||||
|     // "max-lines-per-function": "warn",
 | ||||
|     // "max-nested-callbacks": "warn",
 | ||||
|     // "max-params": "warn",
 | ||||
|     // "max-statements": "warn",
 | ||||
|     "multiline-comment-style": "warn", | ||||
|     "new-cap": "warn", | ||||
|     "no-alert": "warn", | ||||
|     "no-bitwise": "warn", | ||||
|     "no-caller": "warn", | ||||
|     "no-confusing-arrow": "warn", | ||||
|     "no-continue": "warn", | ||||
|     "no-else-return": "warn", | ||||
|     "no-eq-null": "warn", | ||||
|     "no-eval": "warn", | ||||
|     "no-extend-native": "warn", | ||||
|     "no-extra-bind": "warn", | ||||
|     "no-floating-decimal": "warn", | ||||
|     "no-implicit-coercion": "warn", | ||||
|     "no-implicit-globals": "warn", | ||||
|     "no-inline-comments": "warn", | ||||
|     "no-iterator": "warn", | ||||
|     "no-label-var": "warn", | ||||
|     "no-labels": "warn", | ||||
|     "no-lone-blocks": "warn", | ||||
|     "no-lonely-if": "warn", | ||||
|     // "no-magic-numbers": "warn",
 | ||||
|     "no-mixed-operators": "warn", | ||||
|     "no-multi-assign": "warn", | ||||
|     "no-multi-str": "warn", | ||||
|     "no-negated-condition": "warn", | ||||
|     // "no-nested-ternary": "warn",
 | ||||
|     "no-new": "warn", | ||||
|     "no-new-func": "warn", | ||||
|     "no-new-object": "warn", | ||||
|     "no-new-wrappers": "warn", | ||||
|     "no-octal-escape": "warn", | ||||
|     "no-param-reassign": "warn", | ||||
|     "no-plusplus": "warn", | ||||
|     "no-proto": "warn", | ||||
|     "no-restricted-exports": "warn", | ||||
|     "no-restricted-globals": "warn", | ||||
|     "no-restricted-imports": "warn", | ||||
|     "no-restricted-properties": "warn", | ||||
|     "no-restricted-syntax": "warn", | ||||
|     "no-return-assign": "warn", | ||||
|     // "no-return-await": "warn",
 | ||||
|     "no-script-url": "warn", | ||||
|     "no-sequences": "warn", | ||||
|     // "no-ternary": "off",
 | ||||
|     "no-throw-literal": "warn", | ||||
|     "no-undef": "off", | ||||
|     "no-undef-init": "warn", | ||||
|     // "no-undefined": "warn",
 | ||||
|     // "no-underscore-dangle": "warn",
 | ||||
|     "no-unneeded-ternary": "warn", | ||||
|     "no-useless-call": "warn", | ||||
|     "no-useless-computed-key": "warn", | ||||
|     "no-useless-concat": "warn", | ||||
|     "no-useless-rename": "warn", | ||||
|     "no-useless-return": "warn", | ||||
|     "no-var": "warn", | ||||
|     "no-void": "warn", | ||||
|     "no-warning-comments": "warn", | ||||
|     // "object-shorthand": "warn",
 | ||||
|     "operator-assignment": "warn", | ||||
|     "prefer-arrow-callback": "warn", | ||||
|     "prefer-const": "warn", | ||||
|     "prefer-destructuring": ["warn", { array: false, object: true }], | ||||
|     "prefer-exponentiation-operator": "warn", | ||||
|     "prefer-named-capture-group": "warn", | ||||
|     "prefer-numeric-literals": "warn", | ||||
|     // "prefer-object-has-own": "warn",
 | ||||
|     "prefer-object-spread": "warn", | ||||
|     "prefer-promise-reject-errors": "warn", | ||||
|     "prefer-regex-literals": "warn", | ||||
|     "prefer-rest-params": "warn", | ||||
|     "prefer-spread": "warn", | ||||
|     "prefer-template": "warn", | ||||
|     // "quote-props": "warn",
 | ||||
|     radix: "warn", | ||||
|     "require-unicode-regexp": "warn", | ||||
|     // "sort-imports": "warn",
 | ||||
|     // "sort-keys": "warn",
 | ||||
|     "sort-vars": "warn", | ||||
|     "spaced-comment": "warn", | ||||
|     strict: "warn", | ||||
|     "symbol-description": "warn", | ||||
|     "vars-on-top": "warn", | ||||
|     yoda: "warn", | ||||
| 
 | ||||
|     /* TYPESCRIPT */ | ||||
| 
 | ||||
|     "@typescript-eslint/array-type": "warn", | ||||
|     "@typescript-eslint/ban-tslint-comment": "warn", | ||||
|     "@typescript-eslint/class-literal-property-style": "warn", | ||||
|     "@typescript-eslint/consistent-indexed-object-style": "warn", | ||||
|     "@typescript-eslint/consistent-type-assertions": [ | ||||
|       "warn", | ||||
|       { assertionStyle: "as" }, | ||||
|     ], | ||||
|     "@typescript-eslint/consistent-type-exports": "error", | ||||
|     "@typescript-eslint/explicit-module-boundary-types": "warn", | ||||
|     "@typescript-eslint/method-signature-style": ["error", "property"], | ||||
|     "@typescript-eslint/no-base-to-string": "warn", | ||||
|     "@typescript-eslint/no-confusing-non-null-assertion": "warn", | ||||
|     "@typescript-eslint/no-confusing-void-expression": [ | ||||
|       "error", | ||||
|       { ignoreArrowShorthand: true }, | ||||
|     ], | ||||
|     "@typescript-eslint/no-dynamic-delete": "error", | ||||
|     "@typescript-eslint/no-empty-interface": [ | ||||
|       "error", | ||||
|       { allowSingleExtends: true }, | ||||
|     ], | ||||
|     "@typescript-eslint/no-invalid-void-type": "error", | ||||
|     "@typescript-eslint/no-meaningless-void-operator": "error", | ||||
|     "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error", | ||||
|     "@typescript-eslint/no-parameter-properties": "error", | ||||
|     "@typescript-eslint/no-require-imports": "error", | ||||
|     // "@typescript-eslint/no-type-alias": "warn",
 | ||||
|     "@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn", | ||||
|     // "@typescript-eslint/no-unnecessary-condition": "warn",
 | ||||
|     "@typescript-eslint/no-unnecessary-qualifier": "warn", | ||||
|     "@typescript-eslint/no-unnecessary-type-arguments": "warn", | ||||
|     "@typescript-eslint/prefer-enum-initializers": "error", | ||||
|     "@typescript-eslint/prefer-for-of": "error", | ||||
|     "@typescript-eslint/prefer-includes": "error", | ||||
|     "@typescript-eslint/prefer-literal-enum-member": "error", | ||||
|     "@typescript-eslint/prefer-nullish-coalescing": "warn", | ||||
|     "@typescript-eslint/prefer-optional-chain": "warn", | ||||
|     "@typescript-eslint/prefer-readonly": "warn", | ||||
|     // "@typescript-eslint/prefer-readonly-parameter-types": "warn",
 | ||||
|     "@typescript-eslint/prefer-reduce-type-parameter": "warn", | ||||
|     // "@typescript-eslint/prefer-regexp-exec": "warn",
 | ||||
|     "@typescript-eslint/prefer-return-this-type": "warn", | ||||
|     "@typescript-eslint/prefer-string-starts-ends-with": "error", | ||||
|     "@typescript-eslint/promise-function-async": "error", | ||||
|     "@typescript-eslint/require-array-sort-compare": "error", | ||||
|     "@typescript-eslint/sort-type-union-intersection-members": "warn", | ||||
|     // "@typescript-eslint/strict-boolean-expressions": "error",
 | ||||
|     "@typescript-eslint/switch-exhaustiveness-check": "error", | ||||
|     "@typescript-eslint/typedef": "error", | ||||
|     "@typescript-eslint/unified-signatures": "error", | ||||
| 
 | ||||
|     /* EXTENSION OF ESLINT */ | ||||
|     "@typescript-eslint/no-duplicate-imports": "error", | ||||
|     "@typescript-eslint/default-param-last": "warn", | ||||
|     "@typescript-eslint/dot-notation": "warn", | ||||
|     "@typescript-eslint/init-declarations": "warn", | ||||
|     "@typescript-eslint/no-array-constructor": "warn", | ||||
|     "@typescript-eslint/no-implied-eval": "warn", | ||||
|     "@typescript-eslint/no-invalid-this": "warn", | ||||
|     "@typescript-eslint/no-loop-func": "warn", | ||||
|     "@typescript-eslint/no-shadow": "warn", | ||||
|     "@typescript-eslint/no-unused-expressions": "warn", | ||||
|     "@typescript-eslint/no-useless-constructor": "warn", | ||||
|     "@typescript-eslint/require-await": "warn", | ||||
| 
 | ||||
|     /* NEXTJS */ | ||||
|     "@next/next/no-img-element": "off", | ||||
|   }, | ||||
| }; | ||||
| @ -1,3 +0,0 @@ | ||||
| { | ||||
|   "extends": "next/core-web-vitals" | ||||
| } | ||||
							
								
								
									
										10
									
								
								.hintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.hintrc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| { | ||||
|   "extends": ["development"], | ||||
|   "hints": { | ||||
|     "no-inline-styles": "off", | ||||
|     "apple-touch-icons": "off", | ||||
|     "compat-api/html": "off", | ||||
|     "axe/text-alternatives": "off", | ||||
|     "axe/parsing": "off" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										296
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										296
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -26,11 +26,14 @@ | ||||
|         "@types/nodemailer": "^6.4.4", | ||||
|         "@types/react": "17.0.40", | ||||
|         "@types/react-dom": "^17.0.13", | ||||
|         "eslint": "8.10.0", | ||||
|         "@types/turndown": "^5.0.1", | ||||
|         "@typescript-eslint/eslint-plugin": "^5.16.0", | ||||
|         "@typescript-eslint/parser": "^5.16.0", | ||||
|         "eslint": "^8.10.0", | ||||
|         "eslint-config-next": "12.1.0", | ||||
|         "prettier-plugin-organize-imports": "^2.3.4", | ||||
|         "tailwindcss": "^3.0.23", | ||||
|         "typescript": "4.6.2" | ||||
|         "typescript": "^4.6.2" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/code-frame": { | ||||
| @ -480,6 +483,12 @@ | ||||
|         "react-dom": ">=16.8" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@types/json-schema": { | ||||
|       "version": "7.0.11", | ||||
|       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", | ||||
|       "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@types/json5": { | ||||
|       "version": "0.0.29", | ||||
|       "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", | ||||
| @ -539,15 +548,54 @@ | ||||
|       "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/parser": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.12.0.tgz", | ||||
|       "integrity": "sha512-MfSwg9JMBojMUoGjUmX+D2stoQj1CBYTCP0qnnVtu9A+YQXVKNtLjasYh+jozOcrb/wau8TCfWOkQTiOAruBog==", | ||||
|     "node_modules/@types/turndown": { | ||||
|       "version": "5.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.1.tgz", | ||||
|       "integrity": "sha512-N8Ad4e3oJxh9n9BiZx9cbe/0M3kqDpOTm2wzj13wdDUxDPjfjloWIJaquZzWE1cYTAHpjOH3rcTnXQdpEfS/SQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/eslint-plugin": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", | ||||
|       "integrity": "sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/scope-manager": "5.12.0", | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.12.0", | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/type-utils": "5.16.0", | ||||
|         "@typescript-eslint/utils": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "functional-red-black-tree": "^1.0.1", | ||||
|         "ignore": "^5.1.8", | ||||
|         "regexpp": "^3.2.0", | ||||
|         "semver": "^7.3.5", | ||||
|         "tsutils": "^3.21.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/typescript-eslint" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "@typescript-eslint/parser": "^5.0.0", | ||||
|         "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" | ||||
|       }, | ||||
|       "peerDependenciesMeta": { | ||||
|         "typescript": { | ||||
|           "optional": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/parser": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.16.0.tgz", | ||||
|       "integrity": "sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.16.0", | ||||
|         "debug": "^4.3.2" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -567,13 +615,13 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/scope-manager": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.12.0.tgz", | ||||
|       "integrity": "sha512-GAMobtIJI8FGf1sLlUWNUm2IOkIjvn7laFWyRx7CLrv6nLBI7su+B7lbStqVlK5NdLvHRFiJo2HhiDF7Ki01WQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz", | ||||
|       "integrity": "sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.12.0" | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.16.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
| @ -583,10 +631,36 @@ | ||||
|         "url": "https://opencollective.com/typescript-eslint" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/type-utils": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz", | ||||
|       "integrity": "sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/utils": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "tsutils": "^3.21.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/typescript-eslint" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "eslint": "*" | ||||
|       }, | ||||
|       "peerDependenciesMeta": { | ||||
|         "typescript": { | ||||
|           "optional": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/types": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.12.0.tgz", | ||||
|       "integrity": "sha512-JowqbwPf93nvf8fZn5XrPGFBdIK8+yx5UEGs2QFAYFI8IWYfrzz+6zqlurGr2ctShMaJxqwsqmra3WXWjH1nRQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.16.0.tgz", | ||||
|       "integrity": "sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
| @ -597,13 +671,13 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/typescript-estree": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.0.tgz", | ||||
|       "integrity": "sha512-Dd9gVeOqt38QHR0BEA8oRaT65WYqPYbIc5tRFQPkfLquVEFPD1HAtbZT98TLBkEcCkvwDYOAvuSvAD9DnQhMfQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz", | ||||
|       "integrity": "sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.12.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "globby": "^11.0.4", | ||||
|         "is-glob": "^4.0.3", | ||||
| @ -623,13 +697,59 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/visitor-keys": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.0.tgz", | ||||
|       "integrity": "sha512-cFwTlgnMV6TgezQynx2c/4/tx9Tufbuo9LPzmWqyRC3QC4qTGkAG1C6pBr0/4I10PAI/FlYunI3vJjIcu+ZHMg==", | ||||
|     "node_modules/@typescript-eslint/utils": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.16.0.tgz", | ||||
|       "integrity": "sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@types/json-schema": "^7.0.9", | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.16.0", | ||||
|         "eslint-scope": "^5.1.1", | ||||
|         "eslint-utils": "^3.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/typescript-eslint" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { | ||||
|       "version": "5.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", | ||||
|       "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "esrecurse": "^4.3.0", | ||||
|         "estraverse": "^4.1.1" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=8.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/utils/node_modules/estraverse": { | ||||
|       "version": "4.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", | ||||
|       "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=4.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@typescript-eslint/visitor-keys": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz", | ||||
|       "integrity": "sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "eslint-visitor-keys": "^3.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -4038,6 +4158,12 @@ | ||||
|         "tippy.js": "^6.3.1" | ||||
|       } | ||||
|     }, | ||||
|     "@types/json-schema": { | ||||
|       "version": "7.0.11", | ||||
|       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", | ||||
|       "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/json5": { | ||||
|       "version": "0.0.29", | ||||
|       "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", | ||||
| @ -4097,42 +4223,76 @@ | ||||
|       "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@typescript-eslint/parser": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.12.0.tgz", | ||||
|       "integrity": "sha512-MfSwg9JMBojMUoGjUmX+D2stoQj1CBYTCP0qnnVtu9A+YQXVKNtLjasYh+jozOcrb/wau8TCfWOkQTiOAruBog==", | ||||
|     "@types/turndown": { | ||||
|       "version": "5.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.1.tgz", | ||||
|       "integrity": "sha512-N8Ad4e3oJxh9n9BiZx9cbe/0M3kqDpOTm2wzj13wdDUxDPjfjloWIJaquZzWE1cYTAHpjOH3rcTnXQdpEfS/SQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@typescript-eslint/eslint-plugin": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", | ||||
|       "integrity": "sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/scope-manager": "5.12.0", | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.12.0", | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/type-utils": "5.16.0", | ||||
|         "@typescript-eslint/utils": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "functional-red-black-tree": "^1.0.1", | ||||
|         "ignore": "^5.1.8", | ||||
|         "regexpp": "^3.2.0", | ||||
|         "semver": "^7.3.5", | ||||
|         "tsutils": "^3.21.0" | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/parser": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.16.0.tgz", | ||||
|       "integrity": "sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.16.0", | ||||
|         "debug": "^4.3.2" | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/scope-manager": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.12.0.tgz", | ||||
|       "integrity": "sha512-GAMobtIJI8FGf1sLlUWNUm2IOkIjvn7laFWyRx7CLrv6nLBI7su+B7lbStqVlK5NdLvHRFiJo2HhiDF7Ki01WQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz", | ||||
|       "integrity": "sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.12.0" | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.16.0" | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/type-utils": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz", | ||||
|       "integrity": "sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/utils": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "tsutils": "^3.21.0" | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/types": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.12.0.tgz", | ||||
|       "integrity": "sha512-JowqbwPf93nvf8fZn5XrPGFBdIK8+yx5UEGs2QFAYFI8IWYfrzz+6zqlurGr2ctShMaJxqwsqmra3WXWjH1nRQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.16.0.tgz", | ||||
|       "integrity": "sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@typescript-eslint/typescript-estree": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.0.tgz", | ||||
|       "integrity": "sha512-Dd9gVeOqt38QHR0BEA8oRaT65WYqPYbIc5tRFQPkfLquVEFPD1HAtbZT98TLBkEcCkvwDYOAvuSvAD9DnQhMfQ==", | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz", | ||||
|       "integrity": "sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.12.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/visitor-keys": "5.16.0", | ||||
|         "debug": "^4.3.2", | ||||
|         "globby": "^11.0.4", | ||||
|         "is-glob": "^4.0.3", | ||||
| @ -4140,13 +4300,45 @@ | ||||
|         "tsutils": "^3.21.0" | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/visitor-keys": { | ||||
|       "version": "5.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.0.tgz", | ||||
|       "integrity": "sha512-cFwTlgnMV6TgezQynx2c/4/tx9Tufbuo9LPzmWqyRC3QC4qTGkAG1C6pBr0/4I10PAI/FlYunI3vJjIcu+ZHMg==", | ||||
|     "@typescript-eslint/utils": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.16.0.tgz", | ||||
|       "integrity": "sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/types": "5.12.0", | ||||
|         "@types/json-schema": "^7.0.9", | ||||
|         "@typescript-eslint/scope-manager": "5.16.0", | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "@typescript-eslint/typescript-estree": "5.16.0", | ||||
|         "eslint-scope": "^5.1.1", | ||||
|         "eslint-utils": "^3.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "eslint-scope": { | ||||
|           "version": "5.1.1", | ||||
|           "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", | ||||
|           "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "esrecurse": "^4.3.0", | ||||
|             "estraverse": "^4.1.1" | ||||
|           } | ||||
|         }, | ||||
|         "estraverse": { | ||||
|           "version": "4.3.0", | ||||
|           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", | ||||
|           "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", | ||||
|           "dev": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@typescript-eslint/visitor-keys": { | ||||
|       "version": "5.16.0", | ||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz", | ||||
|       "integrity": "sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@typescript-eslint/types": "5.16.0", | ||||
|         "eslint-visitor-keys": "^3.0.0" | ||||
|       } | ||||
|     }, | ||||
|  | ||||
| @ -28,10 +28,13 @@ | ||||
|     "@types/nodemailer": "^6.4.4", | ||||
|     "@types/react": "17.0.40", | ||||
|     "@types/react-dom": "^17.0.13", | ||||
|     "eslint": "8.10.0", | ||||
|     "@types/turndown": "^5.0.1", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.16.0", | ||||
|     "@typescript-eslint/parser": "^5.16.0", | ||||
|     "eslint": "^8.10.0", | ||||
|     "eslint-config-next": "12.1.0", | ||||
|     "prettier-plugin-organize-imports": "^2.3.4", | ||||
|     "tailwindcss": "^3.0.23", | ||||
|     "typescript": "4.6.2" | ||||
|     "typescript": "^4.6.2" | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import Button from "components/Button"; | ||||
| import { useAppLayout } from "contexts/AppLayoutContext"; | ||||
| import { StrapiImage } from "graphql/operations-types"; | ||||
| import { useMediaCoarse, useMediaMobile } from "hooks/useMediaQuery"; | ||||
| import { useMediaMobile } from "hooks/useMediaQuery"; | ||||
| import Head from "next/head"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps } from "queries/getAppStaticProps"; | ||||
| @ -27,7 +27,6 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|   const { langui, currencies, languages, subPanel, contentPanel } = props; | ||||
|   const router = useRouter(); | ||||
|   const isMobile = useMediaMobile(); | ||||
|   const isCoarse = useMediaCoarse(); | ||||
|   const appLayout = useAppLayout(); | ||||
| 
 | ||||
|   const sensibilitySwipe = 1.1; | ||||
| @ -70,23 +69,23 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     document.getElementsByTagName("html")[0].style.fontSize = `${ | ||||
|       (appLayout.fontSize || 1) * 100 | ||||
|       (appLayout.fontSize ?? 1) * 100 | ||||
|     }%`;
 | ||||
|   }, [appLayout.fontSize]); | ||||
| 
 | ||||
|   const currencyOptions = currencies.map((currency) => { | ||||
|     return currency.attributes.code; | ||||
|   }); | ||||
|   const currencyOptions = currencies.map( | ||||
|     (currency) => currency.attributes.code | ||||
|   ); | ||||
|   const [currencySelect, setCurrencySelect] = useState<number>(-1); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     appLayout.currency && | ||||
|     if (appLayout.currency) | ||||
|       setCurrencySelect(currencyOptions.indexOf(appLayout.currency)); | ||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||||
|   }, [appLayout.currency]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     currencySelect >= 0 && | ||||
|     if (currencySelect >= 0) | ||||
|       appLayout.setCurrency(currencyOptions[currencySelect]); | ||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||||
|   }, [currencySelect]); | ||||
| @ -98,12 +97,10 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|     } else { | ||||
|       gridCol = "grid-cols-[20rem_20rem_1fr]"; | ||||
|     } | ||||
|   } else if (appLayout.mainPanelReduced) { | ||||
|     gridCol = "grid-cols-[6rem_0px_1fr]"; | ||||
|   } else { | ||||
|     if (appLayout.mainPanelReduced) { | ||||
|       gridCol = "grid-cols-[6rem_0px_1fr]"; | ||||
|     } else { | ||||
|       gridCol = "grid-cols-[20rem_0px_1fr]"; | ||||
|     } | ||||
|     gridCol = "grid-cols-[20rem_0px_1fr]"; | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
| @ -152,7 +149,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|         {/* 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 | ||||
|             (appLayout.mainPanelOpen ?? appLayout.subPanelOpen) && isMobile | ||||
|               ? "[backdrop-filter:blur(2px)]" | ||||
|               : "pointer-events-none touch-none " | ||||
|           }`}
 | ||||
| @ -161,7 +158,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|             className={`absolute bg-shade inset-0 transition-opacity duration-500 
 | ||||
|         ${turnSubIntoContent ? "" : ""} | ||||
|         ${ | ||||
|           (appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile | ||||
|           (appLayout.mainPanelOpen ?? appLayout.subPanelOpen) && isMobile | ||||
|             ? "opacity-60" | ||||
|             : "opacity-0" | ||||
|         }`}
 | ||||
| @ -195,9 +192,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|           ${ | ||||
|             turnSubIntoContent | ||||
|               ? "mobile:border-l-0 mobile:w-full" | ||||
|               : !appLayout.subPanelOpen | ||||
|               ? "mobile:translate-x-[100vw]" | ||||
|               : "" | ||||
|               : !appLayout.subPanelOpen && "mobile:translate-x-[100vw]" | ||||
|           }`}
 | ||||
|           > | ||||
|             {subPanel} | ||||
| @ -338,7 +333,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|                   className="rounded-l-none rounded-r-none border-x-0" | ||||
|                   onClick={() => appLayout.setFontSize(1)} | ||||
|                 > | ||||
|                   {((appLayout.fontSize || 1) * 100).toLocaleString(undefined, { | ||||
|                   {((appLayout.fontSize ?? 1) * 100).toLocaleString(undefined, { | ||||
|                     maximumFractionDigits: 0, | ||||
|                   })} | ||||
|                   % | ||||
| @ -382,8 +377,10 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | ||||
|                 type="text" | ||||
|                 placeholder="<player>" | ||||
|                 className="w-48" | ||||
|                 onInput={(e) => | ||||
|                   appLayout.setPlayerName((e.target as HTMLInputElement).value) | ||||
|                 onInput={(event) => | ||||
|                   appLayout.setPlayerName( | ||||
|                     (event.target as HTMLInputElement).value | ||||
|                   ) | ||||
|                 } | ||||
|               /> | ||||
|             </div> | ||||
|  | ||||
| @ -19,23 +19,22 @@ export default function ChronologyItemComponent( | ||||
|   const { langui } = props; | ||||
| 
 | ||||
|   function generateAnchor(year: number, month: number, day: number): string { | ||||
|     let result: string = ""; | ||||
|     let result = ""; | ||||
|     result += year; | ||||
|     if (month) result += "-" + month.toString().padStart(2, "0"); | ||||
|     if (day) result += "-" + day.toString().padStart(2, "0"); | ||||
|     if (month) result += `- ${month.toString().padStart(2, "0")}`; | ||||
|     if (day) result += `- ${day.toString().padStart(2, "0")}`; | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   function generateYear(displayed_date: string, year: number): string { | ||||
|     if (displayed_date) { | ||||
|       return displayed_date; | ||||
|     } else { | ||||
|       return year.toString(); | ||||
|     } | ||||
|     return year.toString(); | ||||
|   } | ||||
| 
 | ||||
|   function generateDate(month: number, day: number): string { | ||||
|     let lut = [ | ||||
|     const lut = [ | ||||
|       "Jan", | ||||
|       "Feb", | ||||
|       "Mar", | ||||
| @ -50,11 +49,11 @@ export default function ChronologyItemComponent( | ||||
|       "Dec", | ||||
|     ]; | ||||
| 
 | ||||
|     let result: string = ""; | ||||
|     let result = ""; | ||||
|     if (month) { | ||||
|       result += lut[month - 1]; | ||||
|       if (day) { | ||||
|         result += " " + day; | ||||
|         result += ` ${day}`; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
| @ -113,7 +112,7 @@ export default function ChronologyItemComponent( | ||||
|                   </p> | ||||
|                 )} | ||||
|                 {translation.note ? ( | ||||
|                   <em>{"Notes: " + translation.note}</em> | ||||
|                   <em>{`Notes: ${translation.note}`}</em> | ||||
|                 ) : ( | ||||
|                   "" | ||||
|                 )} | ||||
| @ -122,7 +121,7 @@ export default function ChronologyItemComponent( | ||||
| 
 | ||||
|             <p className="text-dark text-xs grid place-self-start grid-flow-col gap-1 mt-1"> | ||||
|               {event.source.data ? ( | ||||
|                 "(" + event.source.data.attributes.name + ")" | ||||
|                 `(${event.source.data.attributes.name})` | ||||
|               ) : ( | ||||
|                 <> | ||||
|                   <span className="material-icons !text-sm">warning</span>No | ||||
|  | ||||
| @ -49,7 +49,7 @@ export default function ThumbnailHeader( | ||||
|         </div> | ||||
|         <div | ||||
|           id={slugify( | ||||
|             prettyinlineTitle(pre_title || "", title, subtitle || "") | ||||
|             prettyinlineTitle(pre_title ?? "", title, subtitle ?? "") | ||||
|           )} | ||||
|           className="grid place-items-center text-center" | ||||
|         > | ||||
| @ -60,7 +60,7 @@ export default function ThumbnailHeader( | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="grid grid-flow-col gap-8"> | ||||
|         {type && type.data && ( | ||||
|         {type?.data && ( | ||||
|           <div className="flex flex-col place-items-center gap-2"> | ||||
|             <h3 className="text-xl">{langui.type}</h3> | ||||
|             <div className="flex flex-row flex-wrap"> | ||||
|  | ||||
| @ -9,11 +9,12 @@ export enum ImageQuality { | ||||
| } | ||||
| 
 | ||||
| export function getAssetURL(url: string, quality: ImageQuality): string { | ||||
|   url = url.replace(/^\/uploads/, "/" + quality); | ||||
|   url = url.replace(/.jpg$/, ".webp"); | ||||
|   url = url.replace(/.png$/, ".webp"); | ||||
|   if (quality === ImageQuality.Og) url = url.replace(/.webp$/, ".jpg"); | ||||
|   return process.env.NEXT_PUBLIC_URL_IMG + url; | ||||
|   let newUrl = url; | ||||
|   newUrl = newUrl.replace(/^\/uploads/u, `/${quality}`); | ||||
|   newUrl = newUrl.replace(/.jpg$/u, ".webp"); | ||||
|   newUrl = newUrl.replace(/.png$/u, ".webp"); | ||||
|   if (quality === ImageQuality.Og) newUrl = newUrl.replace(/.webp$/u, ".jpg"); | ||||
|   return process.env.NEXT_PUBLIC_URL_IMG + newUrl; | ||||
| } | ||||
| 
 | ||||
| export function getImgSizesByMaxSize( | ||||
| @ -24,10 +25,9 @@ export function getImgSizesByMaxSize( | ||||
|   if (width > height) { | ||||
|     if (width < maxSize) return { width: width, height: height }; | ||||
|     return { width: maxSize, height: (height / width) * maxSize }; | ||||
|   } else { | ||||
|     if (height < maxSize) return { width: width, height: height }; | ||||
|     return { width: (width / height) * maxSize, height: maxSize }; | ||||
|   } | ||||
|   if (height < maxSize) return { width: width, height: height }; | ||||
|   return { width: (width / height) * maxSize, height: maxSize }; | ||||
| } | ||||
| 
 | ||||
| export function getImgSizesByQuality( | ||||
| @ -44,6 +44,8 @@ export function getImgSizesByQuality( | ||||
|       return getImgSizesByMaxSize(width, height, 1024); | ||||
|     case ImageQuality.Large: | ||||
|       return getImgSizesByMaxSize(width, height, 2048); | ||||
|     default: | ||||
|       return { width: 0, height: 0 }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -80,25 +82,23 @@ export default function Img(props: ImgProps): JSX.Element { | ||||
|           height={imgSize.height} | ||||
|         /> | ||||
|       ); | ||||
|     } else { | ||||
|       return ( | ||||
|         <Image | ||||
|           className={props.className} | ||||
|           src={getAssetURL( | ||||
|             props.image.url, | ||||
|             props.quality ? props.quality : ImageQuality.Small | ||||
|           )} | ||||
|           alt={props.alt ? props.alt : props.image.alternativeText} | ||||
|           width={props.layout === "fill" ? undefined : imgSize.width} | ||||
|           height={props.layout === "fill" ? undefined : imgSize.height} | ||||
|           layout={props.layout} | ||||
|           objectFit={props.objectFit} | ||||
|           priority={props.priority} | ||||
|           unoptimized | ||||
|         /> | ||||
|       ); | ||||
|     } | ||||
|   } else { | ||||
|     return <></>; | ||||
|     return ( | ||||
|       <Image | ||||
|         className={props.className} | ||||
|         src={getAssetURL( | ||||
|           props.image.url, | ||||
|           props.quality ? props.quality : ImageQuality.Small | ||||
|         )} | ||||
|         alt={props.alt ? props.alt : props.image.alternativeText} | ||||
|         width={props.layout === "fill" ? undefined : imgSize.width} | ||||
|         height={props.layout === "fill" ? undefined : imgSize.height} | ||||
|         layout={props.layout} | ||||
|         objectFit={props.objectFit} | ||||
|         priority={props.priority} | ||||
|         unoptimized | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
|   return <></>; | ||||
| } | ||||
|  | ||||
| @ -16,8 +16,7 @@ type ContentTOCLineProps = { | ||||
| export default function ContentTOCLine( | ||||
|   props: ContentTOCLineProps | ||||
| ): JSX.Element { | ||||
|   const content = props.content; | ||||
|   const langui = props.langui; | ||||
|   const { content, langui } = props; | ||||
| 
 | ||||
|   const [opened, setOpened] = useState(false); | ||||
| 
 | ||||
|  | ||||
| @ -17,10 +17,10 @@ export type LibraryContentPreviewProps = { | ||||
| export default function LibraryContentPreview( | ||||
|   props: LibraryContentPreviewProps | ||||
| ): JSX.Element { | ||||
|   const item = props.item; | ||||
|   const { item } = props; | ||||
| 
 | ||||
|   return ( | ||||
|     <Link href={"/contents/" + item.slug} passHref> | ||||
|     <Link href={`/contents/${item.slug}`} passHref> | ||||
|       <div className="drop-shadow-shade-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform"> | ||||
|         {item.thumbnail.data ? ( | ||||
|           <Img | ||||
|  | ||||
| @ -26,11 +26,11 @@ export type LibraryItemsPreviewProps = { | ||||
| export default function LibraryItemsPreview( | ||||
|   props: LibraryItemsPreviewProps | ||||
| ): JSX.Element { | ||||
|   const item = props.item; | ||||
|   const { item } = props; | ||||
|   const appLayout = useAppLayout(); | ||||
| 
 | ||||
|   return ( | ||||
|     <Link href={"/library/" + item.slug} passHref> | ||||
|     <Link href={`/library/${item.slug}`} passHref> | ||||
|       <div | ||||
|         className={`drop-shadow-shade-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`} | ||||
|       > | ||||
| @ -63,7 +63,7 @@ export default function LibraryItemsPreview( | ||||
|             ))} | ||||
|           </div> | ||||
| 
 | ||||
|           {(item.release_date || item.price) && ( | ||||
|           {(item.release_date ?? item.price) && ( | ||||
|             <div className="grid grid-flow-col w-full"> | ||||
|               {item.release_date && ( | ||||
|                 <p className="mobile:text-xs text-sm"> | ||||
|  | ||||
| @ -4,8 +4,8 @@ import Lightbox from "react-image-lightbox"; | ||||
| 
 | ||||
| export type LightBoxProps = { | ||||
|   setState: | ||||
|     | Dispatch<SetStateAction<boolean>> | ||||
|     | Dispatch<SetStateAction<boolean | undefined>>; | ||||
|     | Dispatch<SetStateAction<boolean | undefined>> | ||||
|     | Dispatch<SetStateAction<boolean>>; | ||||
|   state: boolean; | ||||
|   images: string[]; | ||||
|   index: number; | ||||
|  | ||||
| @ -8,6 +8,7 @@ import Markdown from "markdown-to-jsx"; | ||||
| import { NextRouter } from "next/router"; | ||||
| import { slugify } from "queries/helpers"; | ||||
| import React, { useState } from "react"; | ||||
| import ReactDOMServer from "react-dom/server"; | ||||
| 
 | ||||
| type MarkdawnProps = { | ||||
|   className?: string; | ||||
| @ -41,264 +42,233 @@ export default function Markdawn(props: MarkdawnProps): JSX.Element { | ||||
|             slugify: slugify, | ||||
|             overrides: { | ||||
|               h1: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h1 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h1> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h1 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h1> | ||||
|                 ), | ||||
|               }, | ||||
|               h2: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h2 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h2> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h2 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h2> | ||||
|                 ), | ||||
|               }, | ||||
|               h3: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h3 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h3> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h3 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h3> | ||||
|                 ), | ||||
|               }, | ||||
|               h4: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h4 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h4> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h4 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h4> | ||||
|                 ), | ||||
|               }, | ||||
|               h5: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h5 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h5> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h5 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h5> | ||||
|                 ), | ||||
|               }, | ||||
|               h6: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   id: string; | ||||
|                   style: React.CSSProperties; | ||||
|                   children: React.ReactNode; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <h6 id={props.id} style={props.style}> | ||||
|                       {props.children} | ||||
|                       <HeaderToolTip id={props.id} /> | ||||
|                     </h6> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <h6 id={compProps.id} style={compProps.style}> | ||||
|                     {compProps.children} | ||||
|                     <HeaderToolTip id={compProps.id} /> | ||||
|                   </h6> | ||||
|                 ), | ||||
|               }, | ||||
|               Sep: { | ||||
|                 component: () => { | ||||
|                   return <div className="my-24"></div>; | ||||
|                 }, | ||||
|                 component: () => <div className="my-24"></div>, | ||||
|               }, | ||||
|               SceneBreak: { | ||||
|                 component: (props: { id: string }) => { | ||||
|                   return ( | ||||
|                     <div | ||||
|                       id={props.id} | ||||
|                       className={ | ||||
|                         "h-0 text-center text-3xl text-dark mt-16 mb-20" | ||||
|                       } | ||||
|                     > | ||||
|                       * * * | ||||
|                     </div> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps: { id: string }) => ( | ||||
|                   <div | ||||
|                     id={compProps.id} | ||||
|                     className={"h-0 text-center text-3xl text-dark mt-16 mb-20"} | ||||
|                   > | ||||
|                     * * * | ||||
|                   </div> | ||||
|                 ), | ||||
|               }, | ||||
|               IntraLink: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   children: React.ReactNode; | ||||
|                   target?: string; | ||||
|                   page?: string; | ||||
|                 }) => { | ||||
|                   const slug = props.target | ||||
|                     ? slugify(props.target) | ||||
|                     : slugify(props.children?.toString()); | ||||
|                   const slug = compProps.target | ||||
|                     ? slugify(compProps.target) | ||||
|                     : slugify(compProps.children?.toString()); | ||||
|                   return ( | ||||
|                     <a | ||||
|                       onClick={() => | ||||
|                       onClick={async () => | ||||
|                         router.replace( | ||||
|                           `${props.page ? props.page : ""}#${slug}` | ||||
|                           `${compProps.page ? compProps.page : ""}#${slug}` | ||||
|                         ) | ||||
|                       } | ||||
|                     > | ||||
|                       {props.children} | ||||
|                       {compProps.children} | ||||
|                     </a> | ||||
|                   ); | ||||
|                 }, | ||||
|               }, | ||||
|               player: { | ||||
|                 component: () => { | ||||
|                   return ( | ||||
|                     <span className="text-dark opacity-70"> | ||||
|                       {appLayout.playerName ? appLayout.playerName : "<player>"} | ||||
|                     </span> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: () => ( | ||||
|                   <span className="text-dark opacity-70"> | ||||
|                     {appLayout.playerName ? appLayout.playerName : "<player>"} | ||||
|                   </span> | ||||
|                 ), | ||||
|               }, | ||||
|               Transcript: { | ||||
|                 component: (props) => { | ||||
|                   return ( | ||||
|                     <div className="grid grid-cols-[auto_1fr] mobile:grid-cols-1 gap-x-6 gap-y-2"> | ||||
|                       {props.children} | ||||
|                     </div> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps) => ( | ||||
|                   <div className="grid grid-cols-[auto_1fr] mobile:grid-cols-1 gap-x-6 gap-y-2"> | ||||
|                     {compProps.children} | ||||
|                   </div> | ||||
|                 ), | ||||
|               }, | ||||
|               Line: { | ||||
|                 component: (props) => { | ||||
|                   return ( | ||||
|                     <> | ||||
|                       <strong className="text-dark opacity-60 mobile:!-mb-4"> | ||||
|                         {props.name} | ||||
|                       </strong> | ||||
|                       <p className="whitespace-pre-line">{props.children}</p> | ||||
|                     </> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps) => ( | ||||
|                   <> | ||||
|                     <strong className="text-dark opacity-60 mobile:!-mb-4"> | ||||
|                       {compProps.name} | ||||
|                     </strong> | ||||
|                     <p className="whitespace-pre-line">{compProps.children}</p> | ||||
|                   </> | ||||
|                 ), | ||||
|               }, | ||||
|               InsetBox: { | ||||
|                 component: (props) => { | ||||
|                   return ( | ||||
|                     <InsetBox className="my-12">{props.children}</InsetBox> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps) => ( | ||||
|                   <InsetBox className="my-12">{compProps.children}</InsetBox> | ||||
|                 ), | ||||
|               }, | ||||
|               li: { | ||||
|                 component: (props: { children: React.ReactNode }) => { | ||||
|                   return ( | ||||
|                     <li | ||||
|                       className={ | ||||
|                         props.children && | ||||
|                         props.children?.toString().length > 100 | ||||
|                           ? "my-4" | ||||
|                           : "" | ||||
|                       } | ||||
|                     > | ||||
|                       {props.children} | ||||
|                     </li> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps: { children: React.ReactNode }) => ( | ||||
|                   <li | ||||
|                     className={ | ||||
|                       compProps.children && | ||||
|                       ReactDOMServer.renderToStaticMarkup( | ||||
|                         <>{compProps.children}</> | ||||
|                       ).length > 100 | ||||
|                         ? "my-4" | ||||
|                         : "" | ||||
|                     } | ||||
|                   > | ||||
|                     {compProps.children} | ||||
|                   </li> | ||||
|                 ), | ||||
|               }, | ||||
|               Highlight: { | ||||
|                 component: (props: { children: React.ReactNode }) => { | ||||
|                   return <mark>{props.children}</mark>; | ||||
|                 }, | ||||
|                 component: (compProps: { children: React.ReactNode }) => ( | ||||
|                   <mark>{compProps.children}</mark> | ||||
|                 ), | ||||
|               }, | ||||
|               footer: { | ||||
|                 component: (props: { children: React.ReactNode }) => { | ||||
|                   return ( | ||||
|                     <> | ||||
|                       <HorizontalLine /> | ||||
|                       <div>{props.children}</div> | ||||
|                     </> | ||||
|                   ); | ||||
|                 }, | ||||
|                 component: (compProps: { children: React.ReactNode }) => ( | ||||
|                   <> | ||||
|                     <HorizontalLine /> | ||||
|                     <div>{compProps.children}</div> | ||||
|                   </> | ||||
|                 ), | ||||
|               }, | ||||
|               blockquote: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   children: React.ReactNode; | ||||
|                   cite?: string; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <blockquote> | ||||
|                       {props.cite ? ( | ||||
|                         <> | ||||
|                           “{props.children}” | ||||
|                           <cite>— {props.cite}</cite> | ||||
|                         </> | ||||
|                       ) : ( | ||||
|                         props.children | ||||
|                       )} | ||||
|                     </blockquote> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <blockquote> | ||||
|                     {compProps.cite ? ( | ||||
|                       <> | ||||
|                         “{compProps.children}” | ||||
|                         <cite>— {compProps.cite}</cite> | ||||
|                       </> | ||||
|                     ) : ( | ||||
|                       compProps.children | ||||
|                     )} | ||||
|                   </blockquote> | ||||
|                 ), | ||||
|               }, | ||||
|               img: { | ||||
|                 component: (props: { | ||||
|                 component: (compProps: { | ||||
|                   alt: string; | ||||
|                   src: string; | ||||
|                   width?: number; | ||||
|                   height?: number; | ||||
|                   caption?: string; | ||||
|                   name?: string; | ||||
|                 }) => { | ||||
|                   return ( | ||||
|                     <div | ||||
|                       className="my-8 cursor-pointer" | ||||
|                       onClick={() => { | ||||
|                         setLightboxOpen(true); | ||||
|                         setLightboxImages([ | ||||
|                           props.src.startsWith("/uploads/") | ||||
|                             ? getAssetURL(props.src, ImageQuality.Large) | ||||
|                             : props.src, | ||||
|                         ]); | ||||
|                         setLightboxIndex(0); | ||||
|                       }} | ||||
|                     > | ||||
|                       {props.src.startsWith("/uploads/") ? ( | ||||
|                         <div className="relative w-full aspect-video"> | ||||
|                           <Img | ||||
|                             image={{ | ||||
|                               __typename: "UploadFile", | ||||
|                               alternativeText: props.alt, | ||||
|                               url: props.src, | ||||
|                               width: props.width || 1500, | ||||
|                               height: props.height || 1000, | ||||
|                               caption: props.caption || "", | ||||
|                               name: props.name || "", | ||||
|                             }} | ||||
|                             layout="fill" | ||||
|                             objectFit="contain" | ||||
|                             quality={ImageQuality.Medium} | ||||
|                           ></Img> | ||||
|                         </div> | ||||
|                       ) : ( | ||||
|                         <div className="grid place-content-center"> | ||||
|                           <img {...props} className="max-h-[50vh] " /> | ||||
|                         </div> | ||||
|                       )} | ||||
|                     </div> | ||||
|                   ); | ||||
|                 }, | ||||
|                 }) => ( | ||||
|                   <div | ||||
|                     className="my-8 cursor-pointer" | ||||
|                     onClick={() => { | ||||
|                       setLightboxOpen(true); | ||||
|                       setLightboxImages([ | ||||
|                         compProps.src.startsWith("/uploads/") | ||||
|                           ? getAssetURL(compProps.src, ImageQuality.Large) | ||||
|                           : compProps.src, | ||||
|                       ]); | ||||
|                       setLightboxIndex(0); | ||||
|                     }} | ||||
|                   > | ||||
|                     {compProps.src.startsWith("/uploads/") ? ( | ||||
|                       <div className="relative w-full aspect-video"> | ||||
|                         <Img | ||||
|                           image={{ | ||||
|                             __typename: "UploadFile", | ||||
|                             alternativeText: compProps.alt, | ||||
|                             url: compProps.src, | ||||
|                             width: compProps.width ?? 1500, | ||||
|                             height: compProps.height ?? 1000, | ||||
|                             caption: compProps.caption ?? "", | ||||
|                             name: compProps.name ?? "", | ||||
|                           }} | ||||
|                           layout="fill" | ||||
|                           objectFit="contain" | ||||
|                           quality={ImageQuality.Medium} | ||||
|                         ></Img> | ||||
|                       </div> | ||||
|                     ) : ( | ||||
|                       <div className="grid place-content-center"> | ||||
|                         {/* eslint-disable-next-line jsx-a11y/alt-text */} | ||||
|                         <img {...compProps} className="max-h-[50vh] " /> | ||||
|                       </div> | ||||
|                     )} | ||||
|                   </div> | ||||
|                 ), | ||||
|               }, | ||||
|             }, | ||||
|           }} | ||||
| @ -323,10 +293,9 @@ function HeaderToolTip(props: { id: string }) { | ||||
|           className="material-icons transition-color hover:text-dark cursor-pointer" | ||||
|           onClick={() => { | ||||
|             navigator.clipboard.writeText( | ||||
|               process.env.NEXT_PUBLIC_URL_SELF + | ||||
|                 window.location.pathname + | ||||
|                 "#" + | ||||
|               `${process.env.NEXT_PUBLIC_URL_SELF + window.location.pathname}#${ | ||||
|                 props.id | ||||
|               }` | ||||
|             ); | ||||
|           }} | ||||
|         > | ||||
| @ -344,8 +313,8 @@ export function preprocessMarkDawn(text: string): string { | ||||
|   const visitedSlugs: string[] = []; | ||||
| 
 | ||||
|   const result = text.split("\n").map((line) => { | ||||
|     if (line === "* * *" || line === "---") { | ||||
|       scenebreakIndex++; | ||||
|     if (line === "* * *" ?? line === "---") { | ||||
|       scenebreakIndex += 1; | ||||
|       return `<SceneBreak id="scene-break-${scenebreakIndex}">`; | ||||
|     } | ||||
| 
 | ||||
| @ -393,16 +362,13 @@ function markdawnHeadersParser( | ||||
|   visitedSlugs: string[] | ||||
| ): string { | ||||
|   const lineText = line.slice(headerLevel + 1); | ||||
|   let slug = slugify(lineText); | ||||
|   const slug = slugify(lineText); | ||||
|   let newSlug = slug; | ||||
|   let index = 2; | ||||
|   while (visitedSlugs.includes(newSlug)) { | ||||
|     newSlug = `${slug}-${index}`; | ||||
|     index++; | ||||
|     index += 1; | ||||
|   } | ||||
|   visitedSlugs.push(newSlug); | ||||
|   return `<${headerLevels[headerLevel]} id="${newSlug}">${lineText}</${headerLevels[headerLevel]}>`; | ||||
| } | ||||
| function getAssetUrl(): React.SetStateAction<string[]> { | ||||
|   throw new Error("Function not implemented."); | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,7 @@ type TOCProps = { | ||||
|   router: NextRouter; | ||||
| }; | ||||
| 
 | ||||
| export default function TOC(props: TOCProps): JSX.Element { | ||||
| export default function TOCComponent(props: TOCProps): JSX.Element { | ||||
|   const { router, text, title } = props; | ||||
|   const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title); | ||||
| 
 | ||||
| @ -17,7 +17,7 @@ export default function TOC(props: TOCProps): JSX.Element { | ||||
|       <h3 className="text-xl">Table of content</h3> | ||||
|       <div className="text-left max-w-[14.5rem]"> | ||||
|         <p className="my-2 overflow-x-hidden relative text-ellipsis whitespace-nowrap text-left"> | ||||
|           <a className="" onClick={() => router.replace(`#${toc.slug}`)}> | ||||
|           <a className="" onClick={async () => router.replace(`#${toc.slug}`)}> | ||||
|             {<abbr title={toc.title}>{toc.title}</abbr>} | ||||
|           </a> | ||||
|         </p> | ||||
| @ -50,7 +50,7 @@ function TOCLevel(props: TOCLevelProps): JSX.Element { | ||||
|             <span className="text-dark">{`${parentNumbering}${ | ||||
|               childIndex + 1 | ||||
|             }.`}</span>{" "}
 | ||||
|             <a onClick={() => router.replace(`#${child.slug}`)}> | ||||
|             <a onClick={async () => router.replace(`#${child.slug}`)}> | ||||
|               {<abbr title={child.title}>{child.title}</abbr>} | ||||
|             </a> | ||||
|           </li> | ||||
| @ -72,8 +72,11 @@ export type TOC = { | ||||
| }; | ||||
| 
 | ||||
| export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|   if (!title) title = "Return to top"; | ||||
|   let toc: TOC = { title: title, slug: slugify(title) || "", children: [] }; | ||||
|   const toc: TOC = { | ||||
|     title: title ?? "Return to top", | ||||
|     slug: slugify(title) ?? "", | ||||
|     children: [], | ||||
|   }; | ||||
|   let h2 = -1; | ||||
|   let h3 = -1; | ||||
|   let h4 = -1; | ||||
| @ -99,7 +102,7 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|         slug: getSlug(line), | ||||
|         children: [], | ||||
|       }); | ||||
|       h2++; | ||||
|       h2 += 1; | ||||
|       h3 = -1; | ||||
|       h4 = -1; | ||||
|       h5 = -1; | ||||
| @ -110,7 +113,7 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|         slug: getSlug(line), | ||||
|         children: [], | ||||
|       }); | ||||
|       h3++; | ||||
|       h3 += 1; | ||||
|       h4 = -1; | ||||
|       h5 = -1; | ||||
|       scenebreak = 0; | ||||
| @ -120,7 +123,7 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|         slug: getSlug(line), | ||||
|         children: [], | ||||
|       }); | ||||
|       h4++; | ||||
|       h4 += 1; | ||||
|       h5 = -1; | ||||
|       scenebreak = 0; | ||||
|     } else if (line.startsWith("<h5 id=")) { | ||||
| @ -129,7 +132,7 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|         slug: getSlug(line), | ||||
|         children: [], | ||||
|       }); | ||||
|       h5++; | ||||
|       h5 += 1; | ||||
|       scenebreak = 0; | ||||
|     } else if (line.startsWith("<h6 id=")) { | ||||
|       toc.children[h2].children[h3].children[h4].children[h5].children.push({ | ||||
| @ -138,8 +141,8 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { | ||||
|         children: [], | ||||
|       }); | ||||
|     } else if (line.startsWith(`<SceneBreak`)) { | ||||
|       scenebreak++; | ||||
|       scenebreakIndex++; | ||||
|       scenebreak += 1; | ||||
|       scenebreakIndex += 1; | ||||
| 
 | ||||
|       const child = { | ||||
|         title: `Scene break ${scenebreak}`, | ||||
|  | ||||
| @ -15,10 +15,10 @@ export type PostPreviewProps = { | ||||
| }; | ||||
| 
 | ||||
| export default function PostPreview(props: PostPreviewProps): JSX.Element { | ||||
|   const post = props.post; | ||||
|   const { post } = props; | ||||
| 
 | ||||
|   return ( | ||||
|     <Link href={"/news/" + post.slug} passHref> | ||||
|     <Link href={`/news/${post.slug}`} passHref> | ||||
|       <div className="drop-shadow-shade-xl cursor-pointer grid items-end hover:scale-[1.02] transition-transform"> | ||||
|         {post.thumbnail.data ? ( | ||||
|           <Img | ||||
|  | ||||
| @ -13,9 +13,9 @@ type ReturnButtonProps = { | ||||
| }; | ||||
| 
 | ||||
| export enum ReturnButtonType { | ||||
|   Mobile, | ||||
|   Desktop, | ||||
|   Both, | ||||
|   mobile = "mobile", | ||||
|   desktop = "desktop", | ||||
|   both = "both", | ||||
| } | ||||
| 
 | ||||
| export default function ReturnButton(props: ReturnButtonProps): JSX.Element { | ||||
| @ -24,9 +24,9 @@ export default function ReturnButton(props: ReturnButtonProps): JSX.Element { | ||||
|   return ( | ||||
|     <div | ||||
|       className={`${ | ||||
|         props.displayOn === ReturnButtonType.Mobile | ||||
|         props.displayOn === ReturnButtonType.mobile | ||||
|           ? "desktop:hidden" | ||||
|           : props.displayOn === ReturnButtonType.Desktop | ||||
|           : props.displayOn === ReturnButtonType.desktop | ||||
|           ? "mobile:hidden" | ||||
|           : "" | ||||
|       } ${props.className}`}
 | ||||
|  | ||||
| @ -5,8 +5,8 @@ type ContentPanelProps = { | ||||
| }; | ||||
| 
 | ||||
| export enum ContentPanelWidthSizes { | ||||
|   default, | ||||
|   large, | ||||
|   default = "default", | ||||
|   large = "large", | ||||
| } | ||||
| 
 | ||||
| export default function ContentPanel(props: ContentPanelProps): JSX.Element { | ||||
|  | ||||
| @ -14,7 +14,7 @@ type MainPanelProps = { | ||||
| }; | ||||
| 
 | ||||
| export default function MainPanel(props: MainPanelProps): JSX.Element { | ||||
|   const langui = props.langui; | ||||
|   const { langui } = props; | ||||
|   const router = useRouter(); | ||||
|   const isDesktop = useMediaDesktop(); | ||||
|   const appLayout = useAppLayout(); | ||||
|  | ||||
| @ -3,8 +3,8 @@ import Button from "./Button"; | ||||
| 
 | ||||
| export type PopupProps = { | ||||
|   setState: | ||||
|     | Dispatch<SetStateAction<boolean>> | ||||
|     | Dispatch<SetStateAction<boolean | undefined>>; | ||||
|     | Dispatch<SetStateAction<boolean | undefined>> | ||||
|     | Dispatch<SetStateAction<boolean>>; | ||||
|   state?: boolean; | ||||
|   children: React.ReactNode; | ||||
|   fillViewport?: boolean; | ||||
| @ -19,8 +19,8 @@ export default function Popup(props: PopupProps): JSX.Element { | ||||
|           ? "[backdrop-filter:blur(2px)]" | ||||
|           : "pointer-events-none touch-none" | ||||
|       }`}
 | ||||
|       onKeyUp={(e) => { | ||||
|         if (e.key.match("Escape")) props.setState(false); | ||||
|       onKeyUp={(event) => { | ||||
|         if (event.key.match("Escape")) props.setState(false); | ||||
|       }} | ||||
|       tabIndex={0} | ||||
|     > | ||||
|  | ||||
| @ -14,8 +14,7 @@ type RecorderChipProps = { | ||||
| }; | ||||
| 
 | ||||
| export default function RecorderChip(props: RecorderChipProps): JSX.Element { | ||||
|   const recorder = props.recorder; | ||||
|   const langui = props.langui; | ||||
|   const { recorder, langui } = props; | ||||
| 
 | ||||
|   return ( | ||||
|     <ToolTip | ||||
|  | ||||
| @ -7,7 +7,6 @@ export type SelectProps = { | ||||
|   selected?: number; | ||||
|   allowEmpty?: boolean; | ||||
|   className?: string; | ||||
|   onChange?: Function; | ||||
| }; | ||||
| 
 | ||||
| export default function Select(props: SelectProps): JSX.Element { | ||||
|  | ||||
| @ -4,7 +4,7 @@ import "tippy.js/animations/scale-subtle.css"; | ||||
| interface ToolTipProps extends TippyProps {} | ||||
| 
 | ||||
| export default function ToolTip(props: ToolTipProps): JSX.Element { | ||||
|   let newProps = { ...props }; | ||||
|   const newProps = { ...props }; | ||||
| 
 | ||||
|   // Set defaults
 | ||||
|   if (newProps.delay === undefined) newProps.delay = [150, 0]; | ||||
|  | ||||
| @ -33,6 +33,7 @@ export interface AppLayoutState { | ||||
|   setPlayerName: React.Dispatch<React.SetStateAction<string | undefined>>; | ||||
| } | ||||
| 
 | ||||
| /* eslint-disable @typescript-eslint/no-empty-function */ | ||||
| const initialState: AppLayoutState = { | ||||
|   subPanelOpen: false, | ||||
|   languagePanelOpen: false, | ||||
| @ -57,12 +58,13 @@ const initialState: AppLayoutState = { | ||||
|   setCurrency: () => {}, | ||||
|   setPlayerName: () => {}, | ||||
| }; | ||||
| /* eslint-enable @typescript-eslint/no-empty-function */ | ||||
| 
 | ||||
| const AppContext = React.createContext<AppLayoutState>(initialState); | ||||
| 
 | ||||
| export default AppContext; | ||||
| 
 | ||||
| export function useAppLayout() { | ||||
| export function useAppLayout(): AppLayoutState { | ||||
|   return useContext(AppContext); | ||||
| } | ||||
| 
 | ||||
| @ -70,7 +72,7 @@ type Props = { | ||||
|   children: ReactNode; | ||||
| }; | ||||
| 
 | ||||
| export const AppContextProvider = (props: Props) => { | ||||
| export function AppContextProvider(props: Props): JSX.Element { | ||||
|   const [subPanelOpen, setSubPanelOpen] = useStateWithLocalStorage< | ||||
|     boolean | undefined | ||||
|   >("subPanelOpen", initialState.subPanelOpen); | ||||
| @ -143,4 +145,4 @@ export const AppContextProvider = (props: Props) => { | ||||
|       {props.children} | ||||
|     </AppContext.Provider> | ||||
|   ); | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| /* eslint-disable @typescript-eslint/consistent-indexed-object-style */ | ||||
| /* eslint-disable @typescript-eslint/array-type */ | ||||
| /* eslint-disable no-shadow */ | ||||
| /* eslint-disable id-denylist */ | ||||
| export type Exact<T> = T; | ||||
| export type InputMaybe<T> = T; | ||||
| export type Scalars = { | ||||
| @ -6,30 +10,31 @@ export type Scalars = { | ||||
|   Boolean: boolean; | ||||
|   Int: number; | ||||
|   Float: number; | ||||
|   JSON: any; | ||||
|   DateTime: any; | ||||
|   Time: any; | ||||
|   Upload: any; | ||||
|   LibraryContentRangeDynamicZoneInput: any; | ||||
|   LibraryItemMetadataDynamicZoneInput: any; | ||||
|   SourceSourceDynamicZoneInput: any; | ||||
|   JSON: unknown; | ||||
|   DateTime: unknown; | ||||
|   Time: unknown; | ||||
|   Upload: unknown; | ||||
|   LibraryContentRangeDynamicZoneInput: unknown; | ||||
|   LibraryItemMetadataDynamicZoneInput: unknown; | ||||
|   SourceSourceDynamicZoneInput: unknown; | ||||
| }; | ||||
| 
 | ||||
| /* | ||||
|   The following is generated using https://www.graphql-code-generator.com/
 | ||||
|   With the following codegen.yml: | ||||
| 
 | ||||
|   generates: | ||||
|   operations-types.ts: | ||||
|     plugins: | ||||
|       - typescript-operations | ||||
| 
 | ||||
|   And the schema.graphql and operation.graphql files from this folder. | ||||
|    | ||||
|   But to make the type easier to work with, it went through the following transformation: | ||||
|     - Removed ? | ||||
|     - Removed | null | ||||
| */ | ||||
|  * The following is generated using https://www.graphql-code-generator.com/
 | ||||
|  * With the following codegen.yml: | ||||
|  * | ||||
|  * generates: | ||||
|  * operations-types.ts: | ||||
|  *   plugins: | ||||
|  *     - typescript-operations | ||||
|  * | ||||
|  * And the schema.graphql and operation.graphql files from this folder. | ||||
|  * | ||||
|  * But to make the type easier to work with, it went through the following transformation: | ||||
|  *   - Removed ? | ||||
|  *   - Removed | null | ||||
|  *   - Replaced any by unknown | ||||
|  */ | ||||
| 
 | ||||
| export enum Enum_Componentmetadatabooks_Binding_Type { | ||||
|   Paperback = "Paperback", | ||||
| @ -939,8 +944,8 @@ export type GetLibraryItemQuery = { | ||||
|                   } | ||||
|                 | { | ||||
|                     __typename: "ComponentRangeTimeRange"; | ||||
|                     starting_time: any; | ||||
|                     ending_time: any; | ||||
|                     starting_time: unknown; | ||||
|                     ending_time: unknown; | ||||
|                   } | ||||
|                 | { __typename: "ComponentRangeOther" } | ||||
|                 | { __typename: "Error" } | ||||
| @ -1571,7 +1576,7 @@ export type GetPostQuery = { | ||||
|       attributes: { | ||||
|         __typename: "Post"; | ||||
|         slug: string; | ||||
|         updatedAt: any; | ||||
|         updatedAt: unknown; | ||||
|         date: { | ||||
|           __typename: "ComponentBasicsDatepicker"; | ||||
|           year: number; | ||||
|  | ||||
| @ -36,7 +36,7 @@ import { | ||||
|   GetWebsiteInterfaceQueryVariables, | ||||
| } from "graphql/operations-types"; | ||||
| 
 | ||||
| const graphQL = async (query: string, variables?: string) => { | ||||
| async function graphQL(query: string, variables?: string) { | ||||
|   const res = await fetch(`${process.env.URL_GRAPHQL}`, { | ||||
|     method: "POST", | ||||
|     body: JSON.stringify({ | ||||
| @ -45,11 +45,11 @@ const graphQL = async (query: string, variables?: string) => { | ||||
|     }), | ||||
|     headers: { | ||||
|       "content-type": "application/json", | ||||
|       Authorization: "Bearer " + process.env.ACCESS_TOKEN, | ||||
|       Authorization: `Bearer ${process.env.ACCESS_TOKEN}`, | ||||
|     }, | ||||
|   }); | ||||
|   return (await res.json()).data; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| function getQueryFromOperations(queryName: string): string { | ||||
|   const operations = readFileSync("./src/graphql/operation.graphql", "utf8"); | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| 
 | ||||
| export default function useMediaQuery(query: string): boolean { | ||||
|   const getMatches = (query: string): boolean => { | ||||
|   function getMatches(query: string): boolean { | ||||
|     // Prevents SSR issues
 | ||||
|     if (typeof window !== "undefined") { | ||||
|       return window.matchMedia(query).matches; | ||||
|     } | ||||
|     return false; | ||||
|   }; | ||||
|   } | ||||
| 
 | ||||
|   const [matches, setMatches] = useState<boolean>(getMatches(query)); | ||||
| 
 | ||||
|  | ||||
| @ -3,7 +3,7 @@ import ReturnButton, { | ||||
|   ReturnButtonType, | ||||
| } from "components/PanelComponents/ReturnButton"; | ||||
| import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface FourOhFourProps extends AppStaticProps {} | ||||
| @ -17,18 +17,20 @@ export default function FourOhFour(props: FourOhFourProps): JSX.Element { | ||||
|         href="/" | ||||
|         title="Home" | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Both} | ||||
|         displayOn={ReturnButtonType.both} | ||||
|       /> | ||||
|     </ContentPanel> | ||||
|   ); | ||||
|   return <AppLayout navTitle="404" contentPanel={contentPanel} {...props} />; | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: FourOhFourProps }> { | ||||
|   const props: FourOhFourProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,7 @@ import { AppContextProvider } from "contexts/AppLayoutContext"; | ||||
| import type { AppProps } from "next/app"; | ||||
| import "tailwind.css"; | ||||
| 
 | ||||
| export default function AccordsLibraryApp(props: AppProps) { | ||||
| export default function AccordsLibraryApp(props: AppProps): JSX.Element { | ||||
|   return ( | ||||
|     <AppContextProvider> | ||||
|       <props.Component {...props.pageProps} /> | ||||
|  | ||||
| @ -7,12 +7,13 @@ import Document, { | ||||
| } from "next/document"; | ||||
| 
 | ||||
| class MyDocument extends Document { | ||||
|   // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||
|   static async getInitialProps(ctx: DocumentContext) { | ||||
|     const initialProps = await Document.getInitialProps(ctx); | ||||
|     return { ...initialProps }; | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|   render(): JSX.Element { | ||||
|     return ( | ||||
|       <Html> | ||||
|         <Head> | ||||
|  | ||||
| @ -9,7 +9,7 @@ import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getPost, getPostLanguages } from "graphql/operations"; | ||||
| import { GetPostQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettySlug } from "queries/helpers"; | ||||
| @ -29,7 +29,7 @@ export default function AccordsHandbook( | ||||
|     <SubPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         horizontalLine | ||||
| @ -48,12 +48,12 @@ export default function AccordsHandbook( | ||||
|     <ContentPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -80,23 +80,25 @@ export default function AccordsHandbook( | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: AccordsHandbookProps }> { | ||||
|   const slug = "accords-handbook"; | ||||
|   const props: AccordsHandbookProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     post: ( | ||||
|       await getPost({ | ||||
|         slug: slug, | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).posts.data[0].attributes, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -10,7 +10,7 @@ import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getPost, getPostLanguages } from "graphql/operations"; | ||||
| import { GetPostQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { RequestMailProps, ResponseMailProps } from "pages/api/mail"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| @ -26,7 +26,7 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|   const { langui, post, locales } = props; | ||||
|   const router = useRouter(); | ||||
|   const [formResponse, setFormResponse] = useState(""); | ||||
|   const [formState, setFormState] = useState<"stale" | "ongoing" | "completed">( | ||||
|   const [formState, setFormState] = useState<"completed" | "ongoing" | "stale">( | ||||
|     "stale" | ||||
|   ); | ||||
| 
 | ||||
| @ -37,7 +37,7 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|     <SubPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         horizontalLine | ||||
| @ -56,12 +56,12 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|     <ContentPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -78,10 +78,10 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|             formState !== "stale" && | ||||
|             "opacity-60 cursor-not-allowed touch-none pointer-events-none" | ||||
|           }`}
 | ||||
|           onSubmit={(e) => { | ||||
|             e.preventDefault(); | ||||
|           onSubmit={(event) => { | ||||
|             event.preventDefault(); | ||||
| 
 | ||||
|             const fields = e.target as unknown as { | ||||
|             const fields = event.target as unknown as { | ||||
|               verif: HTMLInputElement; | ||||
|               name: HTMLInputElement; | ||||
|               email: HTMLInputElement; | ||||
| @ -91,7 +91,8 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|             setFormState("ongoing"); | ||||
| 
 | ||||
|             if ( | ||||
|               parseInt(fields.verif.value) == randomNumber1 + randomNumber2 && | ||||
|               parseInt(fields.verif.value, 10) === | ||||
|                 randomNumber1 + randomNumber2 && | ||||
|               formState !== "completed" | ||||
|             ) { | ||||
|               const content: RequestMailProps = { | ||||
| @ -107,9 +108,9 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|                   "Content-type": "application/json; charset=UTF-8", | ||||
|                 }, | ||||
|               }) | ||||
|                 .then((response) => response.json()) | ||||
|                 .then((data: ResponseMailProps) => { | ||||
|                   switch (data.code) { | ||||
|                 .then(async (responseJson) => responseJson.json()) | ||||
|                 .then((response: ResponseMailProps) => { | ||||
|                   switch (response.code) { | ||||
|                     case "OKAY": | ||||
|                       setFormResponse(langui.response_email_success); | ||||
|                       setFormState("completed"); | ||||
| @ -122,7 +123,7 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|                       break; | ||||
| 
 | ||||
|                     default: | ||||
|                       setFormResponse(data.message || ""); | ||||
|                       setFormResponse(response.message ?? ""); | ||||
|                       setFormState("stale"); | ||||
|                       break; | ||||
|                   } | ||||
| @ -223,23 +224,25 @@ export default function AboutUs(props: ContactProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: ContactProps }> { | ||||
|   const slug = "contact"; | ||||
|   const props: ContactProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     post: ( | ||||
|       await getPost({ | ||||
|         slug: slug, | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).posts.data[0].attributes, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,7 @@ import AppLayout from "components/AppLayout"; | ||||
| import NavOption from "components/PanelComponents/NavOption"; | ||||
| import PanelHeader from "components/PanelComponents/PanelHeader"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface AboutUsProps extends AppStaticProps {} | ||||
| @ -36,11 +36,13 @@ export default function AboutUs(props: AboutUsProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: AboutUsProps }> { | ||||
|   const props: AboutUsProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getPost, getPostLanguages } from "graphql/operations"; | ||||
| import { GetPostQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettySlug } from "queries/helpers"; | ||||
| @ -27,7 +27,7 @@ export default function SiteInformation(props: SiteInfoProps): JSX.Element { | ||||
|     <SubPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         horizontalLine | ||||
| @ -46,12 +46,12 @@ export default function SiteInformation(props: SiteInfoProps): JSX.Element { | ||||
|     <ContentPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -78,23 +78,25 @@ export default function SiteInformation(props: SiteInfoProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: SiteInfoProps }> { | ||||
|   const slug = "legality"; | ||||
|   const props: SiteInfoProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     post: ( | ||||
|       await getPost({ | ||||
|         slug: slug, | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).posts.data[0].attributes, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getPost, getPostLanguages } from "graphql/operations"; | ||||
| import { GetPostQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettySlug } from "queries/helpers"; | ||||
| @ -27,7 +27,7 @@ export default function SharingPolicy(props: SharingPolicyProps): JSX.Element { | ||||
|     <SubPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         horizontalLine | ||||
| @ -46,12 +46,12 @@ export default function SharingPolicy(props: SharingPolicyProps): JSX.Element { | ||||
|     <ContentPanel> | ||||
|       <ReturnButton | ||||
|         href="/about-us" | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         langui={langui} | ||||
|         title={langui.about_us} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -78,23 +78,25 @@ export default function SharingPolicy(props: SharingPolicyProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: SharingPolicyProps }> { | ||||
|   const slug = "sharing-policy"; | ||||
|   const props: SharingPolicyProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     post: ( | ||||
|       await getPost({ | ||||
|         slug: slug, | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).posts.data[0].attributes, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -21,10 +21,10 @@ export default async function Mail( | ||||
|   if (req.method === "POST") { | ||||
|     const body = req.body as RequestMailProps; | ||||
| 
 | ||||
|     let transporter = nodemailer.createTransport({ | ||||
|     const transporter = nodemailer.createTransport({ | ||||
|       host: process.env.SMTP_HOST, | ||||
|       port: 587, | ||||
|       secure: false, // true for 465, false for other ports
 | ||||
|       secure: false, | ||||
|       auth: { | ||||
|         user: process.env.SMTP_USER, | ||||
|         pass: process.env.SMTP_PASSWORD, | ||||
| @ -32,7 +32,7 @@ export default async function Mail( | ||||
|     }); | ||||
| 
 | ||||
|     // send mail with defined transport object
 | ||||
|     let info = await transporter | ||||
|     await transporter | ||||
|       .sendMail({ | ||||
|         from: `"${body.name}" <${body.email}>`, | ||||
|         to: "contact@accords-library.com", | ||||
| @ -40,7 +40,7 @@ export default async function Mail( | ||||
|         text: body.message, | ||||
|       }) | ||||
|       .catch((reason: SMTPError) => { | ||||
|         res.status(reason.responseCode || 500).json({ | ||||
|         res.status(reason.responseCode ?? 500).json({ | ||||
|           code: reason.code, | ||||
|           message: reason.response, | ||||
|         }); | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import AppLayout from "components/AppLayout"; | ||||
| import PanelHeader from "components/PanelComponents/PanelHeader"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface ArchivesProps extends AppStaticProps {} | ||||
| @ -22,11 +22,13 @@ export default function Archives(props: ArchivesProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: ArchivesProps }> { | ||||
|   const props: ArchivesProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import AppLayout from "components/AppLayout"; | ||||
| import PanelHeader from "components/PanelComponents/PanelHeader"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface ChroniclesProps extends AppStaticProps {} | ||||
| @ -22,11 +22,13 @@ export default function Chronicles(props: ChroniclesProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps(context: GetStaticPropsContext): Promise<{ | ||||
|   props: ChroniclesProps; | ||||
| }> { | ||||
|   const props: ChroniclesProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,11 @@ import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getContent, getContentsSlugs } from "graphql/operations"; | ||||
| import { GetContentQuery } from "graphql/operations-types"; | ||||
| import { GetStaticPaths, GetStaticProps } from "next"; | ||||
| import { | ||||
|   GetStaticPathsContext, | ||||
|   GetStaticPathsResult, | ||||
|   GetStaticPropsContext, | ||||
| } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettyinlineTitle, prettySlug } from "queries/helpers"; | ||||
| 
 | ||||
| @ -25,7 +29,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element { | ||||
|         href="/contents" | ||||
|         title={"Contents"} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         horizontalLine | ||||
|       /> | ||||
|     </SubPanel> | ||||
| @ -36,7 +40,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element { | ||||
|         href="/contents" | ||||
|         title={"Contents"} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       <div className="grid place-items-center"> | ||||
| @ -99,9 +103,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element { | ||||
|   if (content.categories.data.length > 0) { | ||||
|     description += `${langui.categories}: `; | ||||
|     description += content.categories.data | ||||
|       .map((category) => { | ||||
|         return category.attributes.short; | ||||
|       }) | ||||
|       .map((category) => category.attributes.short) | ||||
|       .join(" | "); | ||||
|     description += "\n"; | ||||
|   } | ||||
| @ -132,27 +134,29 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps(context: GetStaticPropsContext): Promise<{ | ||||
|   props: ContentIndexProps; | ||||
| }> { | ||||
|   const props: ContentIndexProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     content: ( | ||||
|       await getContent({ | ||||
|         slug: context.params?.slug?.toString() || "", | ||||
|         language_code: context.locale || "en", | ||||
|         slug: context.params?.slug?.toString() ?? "", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).contents.data[0].attributes, | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|   type Path = { params: { slug: string }; locale: string }; | ||||
| 
 | ||||
|   const data = await getContentsSlugs({}); | ||||
|   const paths: Path[] = []; | ||||
|   data.contents.data.map((item) => { | ||||
| export async function getStaticPaths( | ||||
|   context: GetStaticPathsContext | ||||
| ): Promise<GetStaticPathsResult> { | ||||
|   const contents = await getContentsSlugs({}); | ||||
|   const paths: GetStaticPathsResult["paths"] = []; | ||||
|   contents.contents.data.map((item) => { | ||||
|     context.locales?.map((local) => { | ||||
|       paths.push({ params: { slug: item.attributes.slug }, locale: local }); | ||||
|     }); | ||||
| @ -161,4 +165,4 @@ export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|     paths, | ||||
|     fallback: false, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -19,7 +19,11 @@ import { | ||||
|   getContentText, | ||||
| } from "graphql/operations"; | ||||
| import { GetContentTextQuery } from "graphql/operations-types"; | ||||
| import { GetStaticPaths, GetStaticProps } from "next"; | ||||
| import { | ||||
|   GetStaticPathsContext, | ||||
|   GetStaticPathsResult, | ||||
|   GetStaticPropsContext, | ||||
| } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { | ||||
| @ -48,7 +52,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { | ||||
|         href={`/contents/${content.slug}`} | ||||
|         title={"Content"} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         horizontalLine | ||||
|       /> | ||||
| 
 | ||||
| @ -163,7 +167,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { | ||||
|         href={`/contents/${content.slug}`} | ||||
|         title={langui.content} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       <div className="grid place-items-center"> | ||||
| @ -192,7 +196,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { | ||||
| 
 | ||||
|         <HorizontalLine /> | ||||
| 
 | ||||
|         {locales.includes(router.locale || "en") ? ( | ||||
|         {locales.includes(router.locale ?? "en") ? ( | ||||
|           <Markdawn router={router} text={content.text_set[0].text} /> | ||||
|         ) : ( | ||||
|           <LanguageSwitcher | ||||
| @ -219,9 +223,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { | ||||
|   if (content.categories.data.length > 0) { | ||||
|     description += `${langui.categories}: `; | ||||
|     description += content.categories.data | ||||
|       .map((category) => { | ||||
|         return category.attributes.short; | ||||
|       }) | ||||
|       .map((category) => category.attributes.short) | ||||
|       .join(" | "); | ||||
|     description += "\n"; | ||||
|   } | ||||
| @ -247,12 +249,14 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
|   const slug = context.params?.slug?.toString() || ""; | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: ContentReadProps }> { | ||||
|   const slug = context.params?.slug?.toString() ?? ""; | ||||
|   const content = ( | ||||
|     await getContentText({ | ||||
|       slug: slug, | ||||
|       language_code: context.locale || "en", | ||||
|       language_code: context.locale ?? "en", | ||||
|     }) | ||||
|   ).contents.data[0]; | ||||
|   const props: ContentReadProps = { | ||||
| @ -261,26 +265,21 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|     contentId: content.id, | ||||
|     locales: ( | ||||
|       await getContentLanguages({ slug: slug }) | ||||
|     ).contents.data[0].attributes.text_set.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).contents.data[0].attributes.text_set.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|   type Path = { | ||||
|     params: { | ||||
|       slug: string; | ||||
|     }; | ||||
|     locale: string; | ||||
|   }; | ||||
| 
 | ||||
|   const data = await getContentsSlugs({}); | ||||
|   const paths: Path[] = []; | ||||
|   data.contents.data.map((item) => { | ||||
| export async function getStaticPaths( | ||||
|   context: GetStaticPathsContext | ||||
| ): Promise<GetStaticPathsResult> { | ||||
|   const contents = await getContentsSlugs({}); | ||||
|   const paths: GetStaticPathsResult["paths"] = []; | ||||
|   contents.contents.data.map((item) => { | ||||
|     context.locales?.map((local) => { | ||||
|       paths.push({ params: { slug: item.attributes.slug }, locale: local }); | ||||
|     }); | ||||
| @ -289,14 +288,13 @@ export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|     paths, | ||||
|     fallback: false, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export function useTesting(props: ContentReadProps) { | ||||
| function useTesting(props: ContentReadProps) { | ||||
|   const router = useRouter(); | ||||
|   const { content, contentId } = props; | ||||
| 
 | ||||
|   const contentURL = | ||||
|     "/admin/content-manager/collectionType/api::content.content/" + contentId; | ||||
|   const contentURL = `/admin/content-manager/collectionType/api::content.content/${contentId}`; | ||||
| 
 | ||||
|   if (router.locale === "en") { | ||||
|     if (content.categories.data.length === 0) { | ||||
| @ -323,18 +321,17 @@ export function useTesting(props: ContentReadProps) { | ||||
|   } | ||||
| 
 | ||||
|   if (content.text_set.length > 1) { | ||||
|     console.warn( | ||||
|       prettyTestError( | ||||
|         router, | ||||
|         "More than one textset for this language", | ||||
|         ["content", "text_set"], | ||||
|         contentURL | ||||
|       ) | ||||
|     prettyTestError( | ||||
|       router, | ||||
|       "More than one textset for this language", | ||||
|       ["content", "text_set"], | ||||
|       contentURL | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   if (content.text_set.length === 1) { | ||||
|     const textset = content.text_set[0]; | ||||
| 
 | ||||
|     if (!textset.text) { | ||||
|       prettyTestError( | ||||
|         router, | ||||
| @ -350,43 +347,41 @@ export function useTesting(props: ContentReadProps) { | ||||
|         ["content", "text_set"], | ||||
|         contentURL | ||||
|       ); | ||||
|     } else if (textset.source_language.data.attributes.code === router.locale) { | ||||
|       // This is a transcript
 | ||||
|       if (textset.transcribers.data.length === 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Missing transcribers attribution", | ||||
|           ["content", "text_set"], | ||||
|           contentURL | ||||
|         ); | ||||
|       } | ||||
|       if (textset.translators.data.length > 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Transcripts shouldn't have translators", | ||||
|           ["content", "text_set"], | ||||
|           contentURL | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       if (textset.source_language.data.attributes.code === router.locale) { | ||||
|         // This is a transcript
 | ||||
|         if (textset.transcribers.data.length === 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing transcribers attribution", | ||||
|             ["content", "text_set"], | ||||
|             contentURL | ||||
|           ); | ||||
|         } | ||||
|         if (textset.translators.data.length > 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Transcripts shouldn't have translators", | ||||
|             ["content", "text_set"], | ||||
|             contentURL | ||||
|           ); | ||||
|         } | ||||
|       } else { | ||||
|         // This is a translation
 | ||||
|         if (textset.translators.data.length === 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing translators attribution", | ||||
|             ["content", "text_set"], | ||||
|             contentURL | ||||
|           ); | ||||
|         } | ||||
|         if (textset.transcribers.data.length > 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Translations shouldn't have transcribers", | ||||
|             ["content", "text_set"], | ||||
|             contentURL | ||||
|           ); | ||||
|         } | ||||
|       // This is a translation
 | ||||
|       if (textset.translators.data.length === 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Missing translators attribution", | ||||
|           ["content", "text_set"], | ||||
|           contentURL | ||||
|         ); | ||||
|       } | ||||
|       if (textset.transcribers.data.length > 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Translations shouldn't have transcribers", | ||||
|           ["content", "text_set"], | ||||
|           contentURL | ||||
|         ); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -12,7 +12,7 @@ import { | ||||
|   GetContentsQuery, | ||||
|   GetWebsiteInterfaceQuery, | ||||
| } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettyinlineTitle, prettySlug } from "queries/helpers"; | ||||
| import { useEffect, useState } from "react"; | ||||
| @ -64,7 +64,7 @@ export default function Contents(props: ContentsProps): JSX.Element { | ||||
|             <> | ||||
|               {name && ( | ||||
|                 <h2 | ||||
|                   key={"h2" + name} | ||||
|                   key={`h2${name}`} | ||||
|                   className="text-2xl pb-2 pt-10 first-of-type:pt-0 flex flex-row place-items-center gap-2" | ||||
|                 > | ||||
|                   {name} | ||||
| @ -76,7 +76,7 @@ export default function Contents(props: ContentsProps): JSX.Element { | ||||
|                 </h2> | ||||
|               )} | ||||
|               <div | ||||
|                 key={"items" + name} | ||||
|                 key={`items${name}`} | ||||
|                 className="grid gap-8 items-end grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]" | ||||
|               > | ||||
|                 {items.map((item) => ( | ||||
| @ -99,10 +99,12 @@ export default function Contents(props: ContentsProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: ContentsProps }> { | ||||
|   const contents = ( | ||||
|     await getContents({ | ||||
|       language_code: context.locale || "en", | ||||
|       language_code: context.locale ?? "en", | ||||
|     }) | ||||
|   ).contents.data; | ||||
| 
 | ||||
| @ -133,7 +135,7 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| function getGroups( | ||||
|   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"], | ||||
| @ -141,55 +143,58 @@ function getGroups( | ||||
|   items: ContentsProps["contents"] | ||||
| ): GroupContentItems { | ||||
|   switch (groupByType) { | ||||
|     case 0: | ||||
|       const typeGroup = new Map(); | ||||
|       typeGroup.set("Drakengard 1", []); | ||||
|       typeGroup.set("Drakengard 1.3", []); | ||||
|       typeGroup.set("Drakengard 2", []); | ||||
|       typeGroup.set("Drakengard 3", []); | ||||
|       typeGroup.set("Drakengard 4", []); | ||||
|       typeGroup.set("NieR Gestalt", []); | ||||
|       typeGroup.set("NieR Replicant", []); | ||||
|       typeGroup.set("NieR Replicant ver.1.22474487139...", []); | ||||
|       typeGroup.set("NieR:Automata", []); | ||||
|       typeGroup.set("NieR Re[in]carnation", []); | ||||
|       typeGroup.set("SINoALICE", []); | ||||
|       typeGroup.set("Voice of Cards", []); | ||||
|       typeGroup.set("Final Fantasy XIV", []); | ||||
|       typeGroup.set("Thou Shalt Not Die", []); | ||||
|       typeGroup.set("Bakuken", []); | ||||
|       typeGroup.set("YoRHa", []); | ||||
|       typeGroup.set("YoRHa Boys", []); | ||||
|       typeGroup.set(langui.no_category, []); | ||||
|     case 0: { | ||||
|       const group = new Map(); | ||||
|       group.set("Drakengard 1", []); | ||||
|       group.set("Drakengard 1.3", []); | ||||
|       group.set("Drakengard 2", []); | ||||
|       group.set("Drakengard 3", []); | ||||
|       group.set("Drakengard 4", []); | ||||
|       group.set("NieR Gestalt", []); | ||||
|       group.set("NieR Replicant", []); | ||||
|       group.set("NieR Replicant ver.1.22474487139...", []); | ||||
|       group.set("NieR:Automata", []); | ||||
|       group.set("NieR Re[in]carnation", []); | ||||
|       group.set("SINoALICE", []); | ||||
|       group.set("Voice of Cards", []); | ||||
|       group.set("Final Fantasy XIV", []); | ||||
|       group.set("Thou Shalt Not Die", []); | ||||
|       group.set("Bakuken", []); | ||||
|       group.set("YoRHa", []); | ||||
|       group.set("YoRHa Boys", []); | ||||
|       group.set(langui.no_category, []); | ||||
| 
 | ||||
|       items.map((item) => { | ||||
|         if (item.attributes.categories.data.length === 0) { | ||||
|           typeGroup.get(langui.no_category)?.push(item); | ||||
|           group.get(langui.no_category)?.push(item); | ||||
|         } else { | ||||
|           item.attributes.categories.data.map((category) => { | ||||
|             typeGroup.get(category.attributes.name)?.push(item); | ||||
|             group.get(category.attributes.name)?.push(item); | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|       return typeGroup; | ||||
|       return group; | ||||
|     } | ||||
| 
 | ||||
|     case 1: | ||||
|       const groupType: GroupContentItems = new Map(); | ||||
|     case 1: { | ||||
|       const group: GroupContentItems = new Map(); | ||||
|       items.map((item) => { | ||||
|         const type = | ||||
|           item.attributes.type.data.attributes.titles.length > 0 | ||||
|             ? item.attributes.type.data.attributes.titles[0].title | ||||
|             : prettySlug(item.attributes.type.data.attributes.slug); | ||||
| 
 | ||||
|         if (!groupType.has(type)) groupType.set(type, []); | ||||
|         groupType.get(type)?.push(item); | ||||
|         if (!group.has(type)) group.set(type, []); | ||||
|         group.get(type)?.push(item); | ||||
|       }); | ||||
| 
 | ||||
|       return groupType; | ||||
|       return group; | ||||
|     } | ||||
| 
 | ||||
|     default: | ||||
|       const groupDefault: GroupContentItems = new Map(); | ||||
|       groupDefault.set("", items); | ||||
|       return groupDefault; | ||||
|     default: { | ||||
|       const group: GroupContentItems = new Map(); | ||||
|       group.set("", items); | ||||
|       return group; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -3,20 +3,20 @@ import Markdawn from "components/Markdown/Markdawn"; | ||||
| import ContentPanel, { | ||||
|   ContentPanelWidthSizes, | ||||
| } from "components/Panels/ContentPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import Script from "next/script"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { useCallback, useState } from "react"; | ||||
| import { default as TurndownService } from "turndown"; | ||||
| 
 | ||||
| interface EditorProps extends AppStaticProps {} | ||||
| 
 | ||||
| export default function Editor(props: EditorProps): JSX.Element { | ||||
|   const { langui } = props; | ||||
|   const router = useRouter(); | ||||
| 
 | ||||
|   const handleInput = useCallback((e) => { | ||||
|     setMarkdown(e.target.value); | ||||
|   const handleInput = useCallback((event) => { | ||||
|     setMarkdown(event.target.value); | ||||
|   }, []); | ||||
| 
 | ||||
|   const [markdown, setMarkdown] = useState(""); | ||||
| @ -53,7 +53,6 @@ export default function Editor(props: EditorProps): JSX.Element { | ||||
|             id="htmlMdTextArea" | ||||
|             title="Ouput textarea" | ||||
|             onPaste={(event) => { | ||||
|               const TurndownService = require("turndown").default; | ||||
|               const turndownService = new TurndownService({ | ||||
|                 headingStyle: "atx", | ||||
|                 codeBlockStyle: "fenced", | ||||
| @ -63,9 +62,9 @@ export default function Editor(props: EditorProps): JSX.Element { | ||||
|               }); | ||||
| 
 | ||||
|               let paste = event.clipboardData.getData("text/html"); | ||||
|               paste = paste.replace(/<\!--.*?-->/g, ""); | ||||
|               paste = paste.replace(/<!--.*?-->/u, ""); | ||||
|               paste = turndownService.turndown(paste); | ||||
|               paste = paste.replace(/<\!--.*?-->/g, ""); | ||||
|               paste = paste.replace(/<!--.*?-->/u, ""); | ||||
| 
 | ||||
|               const target = event.target as HTMLTextAreaElement; | ||||
|               target.value = paste; | ||||
| @ -93,11 +92,13 @@ export default function Editor(props: EditorProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: EditorProps }> { | ||||
|   const props: EditorProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import AppLayout from "components/AppLayout"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface GalleryProps extends AppStaticProps {} | ||||
| @ -22,11 +22,13 @@ export default function Gallery(props: GalleryProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: GalleryProps }> { | ||||
|   const props: GalleryProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ import Markdawn from "components/Markdown/Markdawn"; | ||||
| import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import { getPost, getPostLanguages } from "graphql/operations"; | ||||
| import { GetPostQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { prettySlug } from "queries/helpers"; | ||||
| @ -27,7 +27,7 @@ export default function Home(props: HomeProps): JSX.Element { | ||||
|           Discover • Analyse • Translate • Archive | ||||
|         </h2> | ||||
|       </div> | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -53,23 +53,25 @@ export default function Home(props: HomeProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: HomeProps }> { | ||||
|   const slug = "home"; | ||||
|   const props: HomeProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     post: ( | ||||
|       await getPost({ | ||||
|         slug: slug, | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).posts.data[0].attributes, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -21,7 +21,11 @@ import { | ||||
|   Enum_Componentmetadatabooks_Page_Order, | ||||
|   GetLibraryItemQuery, | ||||
| } from "graphql/operations-types"; | ||||
| import { GetStaticPaths, GetStaticProps } from "next"; | ||||
| import { | ||||
|   GetStaticPathsContext, | ||||
|   GetStaticPathsResult, | ||||
|   GetStaticPropsContext, | ||||
| } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { | ||||
| @ -64,7 +68,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | ||||
|         href="/library/" | ||||
|         title={langui.library} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         horizontalLine | ||||
|       /> | ||||
| 
 | ||||
| @ -122,7 +126,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | ||||
|         href="/library/" | ||||
|         title={langui.library} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         className="mb-10" | ||||
|       /> | ||||
|       <div className="grid place-items-center gap-12"> | ||||
| @ -189,12 +193,9 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | ||||
|                   onClick={() => { | ||||
|                     setLightboxOpen(true); | ||||
|                     setLightboxImages( | ||||
|                       item.gallery.data.map((image) => { | ||||
|                         return getAssetURL( | ||||
|                           image.attributes.url, | ||||
|                           ImageQuality.Large | ||||
|                         ); | ||||
|                       }) | ||||
|                       item.gallery.data.map((image) => | ||||
|                         getAssetURL(image.attributes.url, ImageQuality.Large) | ||||
|                       ) | ||||
|                     ); | ||||
|                     setLightboxIndex(index); | ||||
|                   }} | ||||
| @ -408,11 +409,13 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: LibrarySlugProps }> { | ||||
|   const item = ( | ||||
|     await getLibraryItem({ | ||||
|       slug: context.params?.slug?.toString() || "", | ||||
|       language_code: context.locale || "en", | ||||
|       slug: context.params?.slug?.toString() ?? "", | ||||
|       language_code: context.locale ?? "en", | ||||
|     }) | ||||
|   ).libraryItems.data[0]; | ||||
|   const props: LibrarySlugProps = { | ||||
| @ -423,19 +426,14 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|   type Path = { | ||||
|     params: { | ||||
|       slug: string; | ||||
|     }; | ||||
|     locale: string; | ||||
|   }; | ||||
| 
 | ||||
|   const data = await getLibraryItemsSlugs({}); | ||||
|   const paths: Path[] = []; | ||||
|   data.libraryItems.data.map((item) => { | ||||
| export async function getStaticPaths( | ||||
|   context: GetStaticPathsContext | ||||
| ): Promise<GetStaticPathsResult> { | ||||
|   const libraryItems = await getLibraryItemsSlugs({}); | ||||
|   const paths: GetStaticPathsResult["paths"] = []; | ||||
|   libraryItems.libraryItems.data.map((item) => { | ||||
|     context.locales?.map((local) => { | ||||
|       paths.push({ params: { slug: item.attributes.slug }, locale: local }); | ||||
|     }); | ||||
| @ -444,15 +442,13 @@ export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|     paths, | ||||
|     fallback: false, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| function useTesting(props: LibrarySlugProps) { | ||||
|   const { item, itemId } = props; | ||||
|   const router = useRouter(); | ||||
| 
 | ||||
|   const libraryItemURL = | ||||
|     "/admin/content-manager/collectionType/api::library-item.library-item/" + | ||||
|     itemId; | ||||
|   const libraryItemURL = `/admin/content-manager/collectionType/api::library-item.library-item/${itemId}`; | ||||
| 
 | ||||
|   sortContent(item.contents); | ||||
| 
 | ||||
| @ -472,269 +468,264 @@ function useTesting(props: LibrarySlugProps) { | ||||
|         ["libraryItem"], | ||||
|         libraryItemURL | ||||
|       ); | ||||
|     } else if ( | ||||
|       item.metadata[0].__typename === "ComponentMetadataGroup" && | ||||
|       (item.metadata[0].subtype.data.attributes.slug === "relation-set" || | ||||
|         item.metadata[0].subtype.data.attributes.slug === "variant-set") | ||||
|     ) { | ||||
|       // This is a group type item
 | ||||
|       if (item.price) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Group-type items shouldn't have price", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
|       if (item.size) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Group-type items shouldn't have size", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
|       if (item.release_date) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Group-type items shouldn't have release_date", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
|       if (item.contents.data.length > 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Group-type items shouldn't have contents", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
|       if (item.subitems.data.length === 0) { | ||||
|         prettyTestError( | ||||
|           router, | ||||
|           "Group-type items should have subitems", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       if ( | ||||
|         item.metadata[0].__typename === "ComponentMetadataGroup" && | ||||
|         (item.metadata[0].subtype.data.attributes.slug === "relation-set" || | ||||
|           item.metadata[0].subtype.data.attributes.slug === "variant-set") | ||||
|       ) { | ||||
|         // This is a group type item
 | ||||
|         if (item.price) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Group-type items shouldn't have price", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|         if (item.size) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Group-type items shouldn't have size", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|         if (item.release_date) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Group-type items shouldn't have release_date", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|         if (item.contents.data.length > 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Group-type items shouldn't have contents", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|       // This is a normal item
 | ||||
| 
 | ||||
|       if (item.metadata[0].__typename === "ComponentMetadataGroup") { | ||||
|         if (item.subitems.data.length === 0) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Group-type items should have subitems", | ||||
|             "Group-type item should have subitems", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (item.price) { | ||||
|         if (!item.price.amount) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing amount", | ||||
|             ["libraryItem", "price"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|         if (!item.price.currency) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing currency", | ||||
|             ["libraryItem", "price"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|       } else { | ||||
|         // This is a normal item
 | ||||
|         prettyTestWarning( | ||||
|           router, | ||||
|           "Missing price", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|         if (item.metadata[0].__typename === "ComponentMetadataGroup") { | ||||
|           if (item.subitems.data.length === 0) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Group-type item should have subitems", | ||||
|               ["libraryItem"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         if (!item.price) { | ||||
|           prettyTestWarning( | ||||
|             router, | ||||
|             "Missing price", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } else { | ||||
|           if (!item.price.amount) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Missing amount", | ||||
|               ["libraryItem", "price"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|           if (!item.price.currency) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Missing currency", | ||||
|               ["libraryItem", "price"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         if (!item.digital) { | ||||
|           if (!item.size) { | ||||
|       if (!item.digital) { | ||||
|         if (item.size) { | ||||
|           if (!item.size.width) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing size", | ||||
|               ["libraryItem"], | ||||
|               "Missing width", | ||||
|               ["libraryItem", "size"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } else { | ||||
|             if (!item.size.width) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing width", | ||||
|                 ["libraryItem", "size"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
|             if (!item.size.height) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing height", | ||||
|                 ["libraryItem", "size"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
|             if (!item.size.thickness) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing thickness", | ||||
|                 ["libraryItem", "size"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         if (!item.release_date) { | ||||
|           if (!item.size.height) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing height", | ||||
|               ["libraryItem", "size"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|           if (!item.size.thickness) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing thickness", | ||||
|               ["libraryItem", "size"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|         } else { | ||||
|           prettyTestWarning( | ||||
|             router, | ||||
|             "Missing release_date", | ||||
|             "Missing size", | ||||
|             ["libraryItem"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } else { | ||||
|           if (!item.release_date.year) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Missing year", | ||||
|               ["libraryItem", "release_date"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|           if (!item.release_date.month) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Missing month", | ||||
|               ["libraryItem", "release_date"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|           if (!item.release_date.day) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               "Missing day", | ||||
|               ["libraryItem", "release_date"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|         if (item.contents.data.length === 0) { | ||||
|           prettyTestWarning( | ||||
|       if (item.release_date) { | ||||
|         if (!item.release_date.year) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing contents", | ||||
|             ["libraryItem"], | ||||
|             "Missing year", | ||||
|             ["libraryItem", "release_date"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } else { | ||||
|           let currentRangePage = 0; | ||||
|           item.contents.data.map((content) => { | ||||
|             const contentURL = | ||||
|               "/admin/content-manager/collectionType/api::content.content/" + | ||||
|               content.id; | ||||
|         } | ||||
|         if (!item.release_date.month) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing month", | ||||
|             ["libraryItem", "release_date"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|         if (!item.release_date.day) { | ||||
|           prettyTestError( | ||||
|             router, | ||||
|             "Missing day", | ||||
|             ["libraryItem", "release_date"], | ||||
|             libraryItemURL | ||||
|           ); | ||||
|         } | ||||
|       } else { | ||||
|         prettyTestWarning( | ||||
|           router, | ||||
|           "Missing release_date", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|             if (content.attributes.scan_set.length === 0) { | ||||
|               prettyTestWarning( | ||||
|       if (item.contents.data.length === 0) { | ||||
|         prettyTestWarning( | ||||
|           router, | ||||
|           "Missing contents", | ||||
|           ["libraryItem"], | ||||
|           libraryItemURL | ||||
|         ); | ||||
|       } else { | ||||
|         let currentRangePage = 0; | ||||
|         item.contents.data.map((content) => { | ||||
|           const contentURL = `/admin/content-manager/collectionType/api::content.content/${content.id}`; | ||||
| 
 | ||||
|           if (content.attributes.scan_set.length === 0) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing scan_set", | ||||
|               ["libraryItem", "content", content.id], | ||||
|               contentURL | ||||
|             ); | ||||
|           } | ||||
|           if (content.attributes.range.length === 0) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing range", | ||||
|               ["libraryItem", "content", content.id], | ||||
|               contentURL | ||||
|             ); | ||||
|           } else if ( | ||||
|             content.attributes.range[0].__typename === "ComponentRangePageRange" | ||||
|           ) { | ||||
|             if ( | ||||
|               content.attributes.range[0].starting_page < | ||||
|               currentRangePage + 1 | ||||
|             ) { | ||||
|               prettyTestError( | ||||
|                 router, | ||||
|                 "Missing scan_set", | ||||
|                 ["libraryItem", "content", content.id], | ||||
|                 contentURL | ||||
|               ); | ||||
|             } | ||||
|             if (content.attributes.range.length === 0) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing range", | ||||
|                 ["libraryItem", "content", content.id], | ||||
|                 contentURL | ||||
|                 `Overlapping pages ${content.attributes.range[0].starting_page} to ${currentRangePage}`, | ||||
|                 ["libraryItem", "content", content.id, "range"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } else if ( | ||||
|               content.attributes.range[0].__typename === | ||||
|               "ComponentRangePageRange" | ||||
|               content.attributes.range[0].starting_page > | ||||
|               currentRangePage + 1 | ||||
|             ) { | ||||
|               if ( | ||||
|                 content.attributes.range[0].starting_page < | ||||
|                 currentRangePage + 1 | ||||
|               ) { | ||||
|                 prettyTestError( | ||||
|                   router, | ||||
|                   `Overlapping pages ${content.attributes.range[0].starting_page} to ${currentRangePage}`, | ||||
|                   ["libraryItem", "content", content.id, "range"], | ||||
|                   libraryItemURL | ||||
|                 ); | ||||
|               } else if ( | ||||
|                 content.attributes.range[0].starting_page > | ||||
|                 currentRangePage + 1 | ||||
|               ) { | ||||
|                 prettyTestError( | ||||
|                   router, | ||||
|                   `Missing pages ${currentRangePage + 1} to ${ | ||||
|                     content.attributes.range[0].starting_page - 1 | ||||
|                   }`,
 | ||||
|                   ["libraryItem", "content", content.id, "range"], | ||||
|                   libraryItemURL | ||||
|                 ); | ||||
|               } | ||||
| 
 | ||||
|               if (!content.attributes.content.data) { | ||||
|                 prettyTestWarning( | ||||
|                   router, | ||||
|                   "Missing content", | ||||
|                   ["libraryItem", "content", content.id, "range"], | ||||
|                   libraryItemURL | ||||
|                 ); | ||||
|               } | ||||
| 
 | ||||
|               currentRangePage = content.attributes.range[0].ending_page; | ||||
|             } | ||||
|           }); | ||||
| 
 | ||||
|           if (item.metadata[0].__typename === "ComponentMetadataBooks") { | ||||
|             if (currentRangePage < item.metadata[0].page_count) { | ||||
|               prettyTestError( | ||||
|                 router, | ||||
|                 `Missing pages ${currentRangePage + 1} to ${ | ||||
|                   item.metadata[0].page_count | ||||
|                   content.attributes.range[0].starting_page - 1 | ||||
|                 }`,
 | ||||
|                 ["libraryItem", "content"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } else if (currentRangePage > item.metadata[0].page_count) { | ||||
|               prettyTestError( | ||||
|                 router, | ||||
|                 `Page overflow, content references pages up to ${currentRangePage} when the highest expected was ${item.metadata[0].page_count}`, | ||||
|                 ["libraryItem", "content"], | ||||
|                 ["libraryItem", "content", content.id, "range"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
| 
 | ||||
|             if (item.metadata[0].languages.data.length === 0) { | ||||
|             if (!content.attributes.content.data) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing language", | ||||
|                 ["libraryItem", "metadata"], | ||||
|                 "Missing content", | ||||
|                 ["libraryItem", "content", content.id, "range"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
| 
 | ||||
|             if (!item.metadata[0].page_count) { | ||||
|               prettyTestWarning( | ||||
|                 router, | ||||
|                 "Missing page_count", | ||||
|                 ["libraryItem", "metadata"], | ||||
|                 libraryItemURL | ||||
|               ); | ||||
|             } | ||||
|             currentRangePage = content.attributes.range[0].ending_page; | ||||
|           } | ||||
|         }); | ||||
| 
 | ||||
|         if (item.metadata[0].__typename === "ComponentMetadataBooks") { | ||||
|           if (currentRangePage < item.metadata[0].page_count) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               `Missing pages ${currentRangePage + 1} to ${ | ||||
|                 item.metadata[0].page_count | ||||
|               }`,
 | ||||
|               ["libraryItem", "content"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } else if (currentRangePage > item.metadata[0].page_count) { | ||||
|             prettyTestError( | ||||
|               router, | ||||
|               `Page overflow, content references pages up to ${currentRangePage} when the highest expected was ${item.metadata[0].page_count}`, | ||||
|               ["libraryItem", "content"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
| 
 | ||||
|           if (item.metadata[0].languages.data.length === 0) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing language", | ||||
|               ["libraryItem", "metadata"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
| 
 | ||||
|           if (!item.metadata[0].page_count) { | ||||
|             prettyTestWarning( | ||||
|               router, | ||||
|               "Missing page_count", | ||||
|               ["libraryItem", "metadata"], | ||||
|               libraryItemURL | ||||
|             ); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
| @ -14,7 +14,7 @@ import { | ||||
|   GetLibraryItemsPreviewQuery, | ||||
|   GetWebsiteInterfaceQuery, | ||||
| } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { convertPrice, prettyDate, prettyinlineTitle } from "queries/helpers"; | ||||
| import { useEffect, useState } from "react"; | ||||
| @ -29,7 +29,7 @@ type GroupLibraryItems = Map< | ||||
| >; | ||||
| 
 | ||||
| export default function Library(props: LibraryProps): JSX.Element { | ||||
|   const { langui, items, currencies } = props; | ||||
|   const { langui, items: libraryItems, currencies } = props; | ||||
| 
 | ||||
|   const [showSubitems, setShowSubitems] = useState<boolean>(false); | ||||
|   const [showPrimaryItems, setShowPrimaryItems] = useState<boolean>(true); | ||||
| @ -38,7 +38,12 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|   const [groupingMethod, setGroupingMethod] = useState<number>(-1); | ||||
| 
 | ||||
|   const [filteredItems, setFilteredItems] = useState<LibraryProps["items"]>( | ||||
|     filterItems(showSubitems, showPrimaryItems, showSecondaryItems, items) | ||||
|     filterItems( | ||||
|       showSubitems, | ||||
|       showPrimaryItems, | ||||
|       showSecondaryItems, | ||||
|       libraryItems | ||||
|     ) | ||||
|   ); | ||||
| 
 | ||||
|   const [sortedItems, setSortedItem] = useState<LibraryProps["items"]>( | ||||
| @ -51,9 +56,14 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setFilteredItems( | ||||
|       filterItems(showSubitems, showPrimaryItems, showSecondaryItems, items) | ||||
|       filterItems( | ||||
|         showSubitems, | ||||
|         showPrimaryItems, | ||||
|         showSecondaryItems, | ||||
|         libraryItems | ||||
|       ) | ||||
|     ); | ||||
|   }, [showSubitems, items, showPrimaryItems, showSecondaryItems]); | ||||
|   }, [showSubitems, libraryItems, showPrimaryItems, showSecondaryItems]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setSortedItem(sortBy(sortingMethod, filteredItems, currencies)); | ||||
| @ -116,7 +126,7 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|             <> | ||||
|               {name && ( | ||||
|                 <h2 | ||||
|                   key={"h2" + name} | ||||
|                   key={`h2${name}`} | ||||
|                   className="text-2xl pb-2 pt-10 first-of-type:pt-0 flex flex-row place-items-center gap-2" | ||||
|                 > | ||||
|                   {name} | ||||
| @ -128,7 +138,7 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|                 </h2> | ||||
|               )} | ||||
|               <div | ||||
|                 key={"items" + name} | ||||
|                 key={`items${name}`} | ||||
|                 className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0" | ||||
|               > | ||||
|                 {items.map((item) => ( | ||||
| @ -155,19 +165,21 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: LibraryProps }> { | ||||
|   const props: LibraryProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     items: ( | ||||
|       await getLibraryItemsPreview({ | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).libraryItems.data, | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| function getGroups( | ||||
|   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"], | ||||
| @ -175,7 +187,7 @@ function getGroups( | ||||
|   items: LibraryProps["items"] | ||||
| ): GroupLibraryItems { | ||||
|   switch (groupByType) { | ||||
|     case 0: | ||||
|     case 0: { | ||||
|       const typeGroup = new Map(); | ||||
|       typeGroup.set("Drakengard 1", []); | ||||
|       typeGroup.set("Drakengard 1.3", []); | ||||
| @ -207,63 +219,73 @@ function getGroups( | ||||
|       }); | ||||
| 
 | ||||
|       return typeGroup; | ||||
|     } | ||||
| 
 | ||||
|     case 1: | ||||
|       const groupType: GroupLibraryItems = new Map(); | ||||
|       groupType.set(langui.audio, []); | ||||
|       groupType.set(langui.game, []); | ||||
|       groupType.set(langui.textual, []); | ||||
|       groupType.set(langui.video, []); | ||||
|       groupType.set(langui.other, []); | ||||
|       groupType.set(langui.group, []); | ||||
|       groupType.set(langui.no_type, []); | ||||
|     case 1: { | ||||
|       const group: GroupLibraryItems = new Map(); | ||||
|       group.set(langui.audio, []); | ||||
|       group.set(langui.game, []); | ||||
|       group.set(langui.textual, []); | ||||
|       group.set(langui.video, []); | ||||
|       group.set(langui.other, []); | ||||
|       group.set(langui.group, []); | ||||
|       group.set(langui.no_type, []); | ||||
|       items.map((item) => { | ||||
|         if (item.attributes.metadata.length > 0) { | ||||
|           switch (item.attributes.metadata[0].__typename) { | ||||
|             case "ComponentMetadataAudio": | ||||
|               groupType.get(langui.audio)?.push(item); | ||||
|               group.get(langui.audio)?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataGame": | ||||
|               groupType.get(langui.game)?.push(item); | ||||
|               group.get(langui.game)?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataBooks": | ||||
|               groupType.get(langui.textual)?.push(item); | ||||
|               group.get(langui.textual)?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataVideo": | ||||
|               groupType.get(langui.video)?.push(item); | ||||
|               group.get(langui.video)?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataOther": | ||||
|               groupType.get(langui.other)?.push(item); | ||||
|               group.get(langui.other)?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataGroup": | ||||
|               switch ( | ||||
|                 item.attributes.metadata[0].subitems_type.data.attributes.slug | ||||
|               ) { | ||||
|                 case "audio": | ||||
|                   groupType.get(langui.audio)?.push(item); | ||||
|                   group.get(langui.audio)?.push(item); | ||||
|                   break; | ||||
|                 case "video": | ||||
|                   groupType.get(langui.video)?.push(item); | ||||
|                   group.get(langui.video)?.push(item); | ||||
|                   break; | ||||
|                 case "game": | ||||
|                   groupType.get(langui.game)?.push(item); | ||||
|                   group.get(langui.game)?.push(item); | ||||
|                   break; | ||||
|                 case "textual": | ||||
|                   groupType.get(langui.textual)?.push(item); | ||||
|                   group.get(langui.textual)?.push(item); | ||||
|                   break; | ||||
|                 case "mixed": | ||||
|                   groupType.get(langui.group)?.push(item); | ||||
|                   group.get(langui.group)?.push(item); | ||||
|                   break; | ||||
|                 default: { | ||||
|                   throw new Error( | ||||
|                     "An unexpected subtype of group-metadata was given" | ||||
|                   ); | ||||
|                 } | ||||
|               } | ||||
|               break; | ||||
|             default: { | ||||
|               throw new Error("An unexpected type of metadata was given"); | ||||
|             } | ||||
|           } | ||||
|         } else { | ||||
|           groupType.get(langui.no_type)?.push(item); | ||||
|           group.get(langui.no_type)?.push(item); | ||||
|         } | ||||
|       }); | ||||
|       return groupType; | ||||
|       return group; | ||||
|     } | ||||
| 
 | ||||
|     case 2: | ||||
|     case 2: { | ||||
|       const years: number[] = []; | ||||
|       items.map((item) => { | ||||
|         if (item.attributes.release_date) { | ||||
| @ -271,28 +293,28 @@ function getGroups( | ||||
|             years.push(item.attributes.release_date.year); | ||||
|         } | ||||
|       }); | ||||
|       const groupYear: GroupLibraryItems = new Map(); | ||||
|       years.sort(); | ||||
|       const group: GroupLibraryItems = new Map(); | ||||
|       years.sort((a, b) => a - b); | ||||
|       years.map((year) => { | ||||
|         groupYear.set(year.toString(), []); | ||||
|         group.set(year.toString(), []); | ||||
|       }); | ||||
|       groupYear.set(langui.no_year, []); | ||||
|       group.set(langui.no_year, []); | ||||
|       items.map((item) => { | ||||
|         if (item.attributes.release_date) { | ||||
|           groupYear | ||||
|             .get(item.attributes.release_date.year.toString()) | ||||
|             ?.push(item); | ||||
|           group.get(item.attributes.release_date.year.toString())?.push(item); | ||||
|         } else { | ||||
|           groupYear.get(langui.no_year)?.push(item); | ||||
|           group.get(langui.no_year)?.push(item); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       return groupYear; | ||||
|       return group; | ||||
|     } | ||||
| 
 | ||||
|     default: | ||||
|       const groupDefault: GroupLibraryItems = new Map(); | ||||
|       groupDefault.set("", items); | ||||
|       return groupDefault; | ||||
|     default: { | ||||
|       const group: GroupLibraryItems = new Map(); | ||||
|       group.set("", items); | ||||
|       return group; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -353,13 +375,13 @@ function sortBy( | ||||
|     case 2: | ||||
|       return [...items].sort((a, b) => { | ||||
|         const dateA = | ||||
|           a.attributes.release_date !== null | ||||
|             ? prettyDate(a.attributes.release_date) | ||||
|             : "9999"; | ||||
|           a.attributes.release_date === null | ||||
|             ? "9999" | ||||
|             : prettyDate(a.attributes.release_date); | ||||
|         const dateB = | ||||
|           b.attributes.release_date !== null | ||||
|             ? prettyDate(b.attributes.release_date) | ||||
|             : "9999"; | ||||
|           b.attributes.release_date === null | ||||
|             ? "9999" | ||||
|             : prettyDate(b.attributes.release_date); | ||||
|         return dateA.localeCompare(dateB); | ||||
|       }); | ||||
|     default: | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import AppLayout from "components/AppLayout"; | ||||
| import PanelHeader from "components/PanelComponents/PanelHeader"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface MerchProps extends AppStaticProps {} | ||||
| @ -20,11 +20,13 @@ export default function Merch(props: MerchProps): JSX.Element { | ||||
|   return <AppLayout navTitle={langui.merch} subPanel={subPanel} {...props} />; | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: MerchProps }> { | ||||
|   const props: MerchProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,11 @@ import RecorderChip from "components/RecorderChip"; | ||||
| import ToolTip from "components/ToolTip"; | ||||
| import { getPost, getPostLanguages, getPostsSlugs } from "graphql/operations"; | ||||
| import { GetPostQuery, StrapiImage } from "graphql/operations-types"; | ||||
| import { GetStaticPaths, GetStaticProps } from "next"; | ||||
| import { | ||||
|   GetStaticPathsContext, | ||||
|   GetStaticPathsResult, | ||||
|   GetStaticPropsContext, | ||||
| } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { getStatusDescription, prettySlug } from "queries/helpers"; | ||||
| @ -42,7 +46,7 @@ export default function LibrarySlug(props: PostProps): JSX.Element { | ||||
|         href="/news" | ||||
|         title={langui.news} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         horizontalLine | ||||
|       /> | ||||
| 
 | ||||
| @ -87,7 +91,7 @@ export default function LibrarySlug(props: PostProps): JSX.Element { | ||||
|         href="/news" | ||||
|         title={langui.news} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         className="mb-10" | ||||
|       /> | ||||
| 
 | ||||
| @ -109,7 +113,7 @@ export default function LibrarySlug(props: PostProps): JSX.Element { | ||||
| 
 | ||||
|       <HorizontalLine /> | ||||
| 
 | ||||
|       {locales.includes(router.locale || "en") ? ( | ||||
|       {locales.includes(router.locale ?? "en") ? ( | ||||
|         <Markdawn router={router} text={post.translations[0].body} /> | ||||
|       ) : ( | ||||
|         <LanguageSwitcher | ||||
| @ -138,12 +142,14 @@ export default function LibrarySlug(props: PostProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
|   const slug = context.params?.slug?.toString() || ""; | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: PostProps }> { | ||||
|   const slug = context.params?.slug?.toString() ?? ""; | ||||
|   const post = ( | ||||
|     await getPost({ | ||||
|       slug: slug, | ||||
|       language_code: context.locale || "en", | ||||
|       language_code: context.locale ?? "en", | ||||
|     }) | ||||
|   ).posts.data[0]; | ||||
|   const props: PostProps = { | ||||
| @ -152,26 +158,21 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|     postId: post.id, | ||||
|     locales: ( | ||||
|       await getPostLanguages({ slug: slug }) | ||||
|     ).posts.data[0].attributes.translations.map((translation) => { | ||||
|       return translation.language.data.attributes.code; | ||||
|     }), | ||||
|     ).posts.data[0].attributes.translations.map( | ||||
|       (translation) => translation.language.data.attributes.code | ||||
|     ), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|   type Path = { | ||||
|     params: { | ||||
|       slug: string; | ||||
|     }; | ||||
|     locale: string; | ||||
|   }; | ||||
| 
 | ||||
|   const data = await getPostsSlugs({}); | ||||
|   const paths: Path[] = []; | ||||
|   data.posts.data.map((item) => { | ||||
| export async function getStaticPaths( | ||||
|   context: GetStaticPathsContext | ||||
| ): Promise<GetStaticPathsResult> { | ||||
|   const posts = await getPostsSlugs({}); | ||||
|   const paths: GetStaticPathsResult["paths"] = []; | ||||
|   posts.posts.data.map((item) => { | ||||
|     context.locales?.map((local) => { | ||||
|       paths.push({ params: { slug: item.attributes.slug }, locale: local }); | ||||
|     }); | ||||
| @ -180,4 +181,4 @@ export const getStaticPaths: GetStaticPaths = async (context) => { | ||||
|     paths, | ||||
|     fallback: false, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ import ContentPanel, { | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { getPostsPreview } from "graphql/operations"; | ||||
| import { GetPostsPreviewQuery } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface NewsProps extends AppStaticProps { | ||||
| @ -46,14 +46,16 @@ export default function News(props: NewsProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: NewsProps }> { | ||||
|   const props: NewsProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     posts: await ( | ||||
|       await getPostsPreview({ language_code: context.locale || "en" }) | ||||
|       await getPostsPreview({ language_code: context.locale ?? "en" }) | ||||
|     ).posts.data, | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -12,7 +12,7 @@ import { | ||||
|   GetChronologyItemsQuery, | ||||
|   GetErasQuery, | ||||
| } from "graphql/operations-types"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { useRouter } from "next/router"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| import { | ||||
| @ -31,7 +31,7 @@ export default function Chronology(props: ChronologyProps): JSX.Element { | ||||
|   const { chronologyItems, chronologyEras, langui } = props; | ||||
| 
 | ||||
|   // Group by year the Chronology items
 | ||||
|   let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][][] = | ||||
|   const chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][][] = | ||||
|     []; | ||||
| 
 | ||||
|   chronologyEras.map(() => { | ||||
| @ -44,20 +44,21 @@ export default function Chronology(props: ChronologyProps): JSX.Element { | ||||
|       item.attributes.year > | ||||
|       chronologyEras[currentChronologyEraIndex].attributes.ending_year | ||||
|     ) { | ||||
|       currentChronologyEraIndex++; | ||||
|       currentChronologyEraIndex += 1; | ||||
|     } | ||||
|     if ( | ||||
|       !chronologyItemYearGroups[currentChronologyEraIndex].hasOwnProperty( | ||||
|       Object.prototype.hasOwnProperty.call( | ||||
|         chronologyItemYearGroups[currentChronologyEraIndex], | ||||
|         item.attributes.year | ||||
|       ) | ||||
|     ) { | ||||
|       chronologyItemYearGroups[currentChronologyEraIndex][ | ||||
|         item.attributes.year | ||||
|       ] = [item]; | ||||
|       ].push(item); | ||||
|     } else { | ||||
|       chronologyItemYearGroups[currentChronologyEraIndex][ | ||||
|         item.attributes.year | ||||
|       ].push(item); | ||||
|       ] = [item]; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
| @ -67,22 +68,20 @@ export default function Chronology(props: ChronologyProps): JSX.Element { | ||||
|         href="/wiki" | ||||
|         title={langui.wiki} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Desktop} | ||||
|         displayOn={ReturnButtonType.desktop} | ||||
|         horizontalLine | ||||
|       /> | ||||
| 
 | ||||
|       {chronologyEras.map((era) => ( | ||||
|         <NavOption | ||||
|           key={era.id} | ||||
|           url={"#" + era.attributes.slug} | ||||
|           url={`#${era.attributes.slug}`} | ||||
|           title={ | ||||
|             era.attributes.title.length > 0 | ||||
|               ? era.attributes.title[0].title | ||||
|               : prettySlug(era.attributes.slug) | ||||
|           } | ||||
|           subtitle={ | ||||
|             era.attributes.starting_year + " → " + era.attributes.ending_year | ||||
|           } | ||||
|           subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`} | ||||
|           border | ||||
|         /> | ||||
|       ))} | ||||
| @ -95,7 +94,7 @@ export default function Chronology(props: ChronologyProps): JSX.Element { | ||||
|         href="/wiki" | ||||
|         title={langui.wiki} | ||||
|         langui={langui} | ||||
|         displayOn={ReturnButtonType.Mobile} | ||||
|         displayOn={ReturnButtonType.mobile} | ||||
|         className="mb-10" | ||||
|       /> | ||||
| 
 | ||||
| @ -139,29 +138,29 @@ export default function Chronology(props: ChronologyProps): JSX.Element { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: ChronologyProps }> { | ||||
|   const props: ChronologyProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|     chronologyItems: ( | ||||
|       await getChronologyItems({ | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).chronologyItems.data, | ||||
|     chronologyEras: (await getEras({ language_code: context.locale || "en" })) | ||||
|     chronologyEras: (await getEras({ language_code: context.locale ?? "en" })) | ||||
|       .chronologyEras.data, | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| function useTesting(props: ChronologyProps) { | ||||
|   const router = useRouter(); | ||||
|   const { chronologyItems, chronologyEras } = props; | ||||
|   chronologyEras.map((era) => { | ||||
|     const chronologyErasURL = | ||||
|       "/admin/content-manager/collectionType/api::chronology-era.chronology-era/" + | ||||
|       chronologyItems[0].id; | ||||
|     const chronologyErasURL = `/admin/content-manager/collectionType/api::chronology-era.chronology-era/${chronologyItems[0].id}`; | ||||
| 
 | ||||
|     if (era.attributes.title.length === 0) { | ||||
|       prettyTestError( | ||||
| @ -196,20 +195,11 @@ function useTesting(props: ChronologyProps) { | ||||
|   }); | ||||
| 
 | ||||
|   chronologyItems.map((item) => { | ||||
|     const chronologyItemsURL = | ||||
|       "/admin/content-manager/collectionType/api::chronology-item.chronology-item/" + | ||||
|       chronologyItems[0].id; | ||||
|     const chronologyItemsURL = `/admin/content-manager/collectionType/api::chronology-item.chronology-item/${chronologyItems[0].id}`; | ||||
| 
 | ||||
|     const date = `${item.attributes.year}/${item.attributes.month}/${item.attributes.day}`; | ||||
| 
 | ||||
|     if (!(item.attributes.events.length > 0)) { | ||||
|       prettyTestError( | ||||
|         router, | ||||
|         "No events for this date", | ||||
|         ["chronologyItems", date], | ||||
|         chronologyItemsURL | ||||
|       ); | ||||
|     } else { | ||||
|     if (item.attributes.events.length > 0) { | ||||
|       item.attributes.events.map((event) => { | ||||
|         if (!event.source.data) { | ||||
|           prettyTestError( | ||||
| @ -228,6 +218,13 @@ function useTesting(props: ChronologyProps) { | ||||
|           ); | ||||
|         } | ||||
|       }); | ||||
|     } else { | ||||
|       prettyTestError( | ||||
|         router, | ||||
|         "No events for this date", | ||||
|         ["chronologyItems", date], | ||||
|         chronologyItemsURL | ||||
|       ); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,7 @@ import AppLayout from "components/AppLayout"; | ||||
| import NavOption from "components/PanelComponents/NavOption"; | ||||
| import PanelHeader from "components/PanelComponents/PanelHeader"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; | ||||
| 
 | ||||
| interface WikiProps extends AppStaticProps {} | ||||
| @ -23,11 +23,13 @@ export default function Wiki(props: WikiProps): JSX.Element { | ||||
|   return <AppLayout navTitle={langui.wiki} subPanel={subPanel} {...props} />; | ||||
| } | ||||
| 
 | ||||
| export const getStaticProps: GetStaticProps = async (context) => { | ||||
| export async function getStaticProps( | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<{ props: WikiProps }> { | ||||
|   const props: WikiProps = { | ||||
|     ...(await getAppStaticProps(context)), | ||||
|   }; | ||||
|   return { | ||||
|     props: props, | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -8,8 +8,7 @@ import { | ||||
|   GetLanguagesQuery, | ||||
|   GetWebsiteInterfaceQuery, | ||||
| } from "graphql/operations-types"; | ||||
| import { GetStaticPropsContext, PreviewData } from "next"; | ||||
| import { ParsedUrlQuery } from "querystring"; | ||||
| import { GetStaticPropsContext } from "next"; | ||||
| 
 | ||||
| export interface AppStaticProps { | ||||
|   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; | ||||
| @ -18,24 +17,20 @@ export interface AppStaticProps { | ||||
| } | ||||
| 
 | ||||
| export async function getAppStaticProps( | ||||
|   context: GetStaticPropsContext<ParsedUrlQuery, PreviewData> | ||||
|   context: GetStaticPropsContext | ||||
| ): Promise<AppStaticProps> { | ||||
|   const languages = (await getLanguages({})).languages.data; | ||||
|   languages.sort((a, b) => { | ||||
|     return a.attributes.localized_name.localeCompare( | ||||
|       b.attributes.localized_name | ||||
|     ); | ||||
|   }); | ||||
|   languages.sort((a, b) => | ||||
|     a.attributes.localized_name.localeCompare(b.attributes.localized_name) | ||||
|   ); | ||||
| 
 | ||||
|   const currencies = (await getCurrencies({})).currencies.data; | ||||
|   currencies.sort((a, b) => { | ||||
|     return a.attributes.code.localeCompare(b.attributes.code); | ||||
|   }); | ||||
|   currencies.sort((a, b) => a.attributes.code.localeCompare(b.attributes.code)); | ||||
| 
 | ||||
|   return { | ||||
|     langui: ( | ||||
|       await getWebsiteInterface({ | ||||
|         language_code: context.locale || "en", | ||||
|         language_code: context.locale ?? "en", | ||||
|       }) | ||||
|     ).websiteInterfaces.data[0].attributes, | ||||
|     currencies: currencies, | ||||
|  | ||||
| @ -17,13 +17,9 @@ import { NextRouter } from "next/router"; | ||||
| export function prettyDate( | ||||
|   datePicker: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"] | ||||
| ): string { | ||||
|   return ( | ||||
|     datePicker.year + | ||||
|     "/" + | ||||
|     datePicker.month.toString().padStart(2, "0") + | ||||
|     "/" + | ||||
|     datePicker.day.toString().padStart(2, "0") | ||||
|   ); | ||||
|   return `${datePicker.year}/${datePicker.month | ||||
|     .toString() | ||||
|     .padStart(2, "0")}/${datePicker.day.toString().padStart(2, "0")}`;
 | ||||
| } | ||||
| 
 | ||||
| export function prettyPrice( | ||||
| @ -74,9 +70,9 @@ export function prettyinlineTitle( | ||||
|   subtitle: string | ||||
| ): string { | ||||
|   let result = ""; | ||||
|   if (pretitle) result += pretitle + ": "; | ||||
|   if (pretitle) result += `${pretitle}: `; | ||||
|   result += title; | ||||
|   if (subtitle) result += " - " + subtitle; | ||||
|   if (subtitle) result += ` - ${subtitle}`; | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| @ -86,7 +82,6 @@ export function prettyItemType( | ||||
|   }, | ||||
|   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"] | ||||
| ): string { | ||||
|   const type = metadata.__typename; | ||||
|   switch (metadata.__typename) { | ||||
|     case "ComponentMetadataAudio": | ||||
|       return langui.audio; | ||||
| @ -106,6 +101,7 @@ export function prettyItemType( | ||||
| } | ||||
| 
 | ||||
| export function prettyItemSubType(metadata: { | ||||
|   /* eslint-disable @typescript-eslint/no-explicit-any */ | ||||
|   __typename: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number]["__typename"]; | ||||
|   subtype?: any; | ||||
|   platforms?: any; | ||||
| @ -138,6 +134,7 @@ export function prettyItemSubType(metadata: { | ||||
|     default: | ||||
|       return ""; | ||||
|   } | ||||
|   /* eslint-enable @typescript-eslint/no-explicit-any */ | ||||
| } | ||||
| 
 | ||||
| export function prettyLanguage( | ||||
| @ -184,7 +181,7 @@ function prettyTestWritter( | ||||
| ): void { | ||||
|   const line = [ | ||||
|     level, | ||||
|     process.env.NEXT_PUBLIC_URL_SELF + "/" + locale + asPath, | ||||
|     `${process.env.NEXT_PUBLIC_URL_SELF}/${locale}${asPath}`, | ||||
|     locale, | ||||
|     subCategory?.join(" -> "), | ||||
|     message, | ||||
| @ -206,7 +203,7 @@ export function capitalizeString(string: string): string { | ||||
|   } | ||||
| 
 | ||||
|   let words = string.split(" "); | ||||
|   words = words.map((word) => (word = capitalizeWord(word))); | ||||
|   words = words.map((word) => capitalizeWord(word)); | ||||
|   return words.join(" "); | ||||
| } | ||||
| 
 | ||||
| @ -275,20 +272,22 @@ export function getStatusDescription( | ||||
| } | ||||
| 
 | ||||
| export function slugify(string: string | undefined): string { | ||||
|   if (!string) return ""; | ||||
|   if (!string) { | ||||
|     return ""; | ||||
|   } | ||||
|   return string | ||||
|     .replace(/[ÀÁÂÃÄÅàáâãä忯]/g, "a") | ||||
|     .replace(/[çÇ]/g, "c") | ||||
|     .replace(/[ðÐ]/g, "d") | ||||
|     .replace(/[ÈÉÊËéèêë]/g, "e") | ||||
|     .replace(/[ÏïÎîÍíÌì]/g, "i") | ||||
|     .replace(/[Ññ]/g, "n") | ||||
|     .replace(/[øØœŒÕõÔôÓóÒò]/g, "o") | ||||
|     .replace(/[ÜüÛûÚúÙù]/g, "u") | ||||
|     .replace(/[ŸÿÝý]/g, "y") | ||||
|     .replace(/[^a-z0-9- ]/gi, "") | ||||
|     .replace(/[ÀÁÂÃÄÅàáâãä忯]/u, "a") | ||||
|     .replace(/[çÇ]/u, "c") | ||||
|     .replace(/[ðÐ]/u, "d") | ||||
|     .replace(/[ÈÉÊËéèêë]/u, "e") | ||||
|     .replace(/[ÏïÎîÍíÌì]/u, "i") | ||||
|     .replace(/[Ññ]/u, "n") | ||||
|     .replace(/[øØœŒÕõÔôÓóÒò]/u, "o") | ||||
|     .replace(/[ÜüÛûÚúÙù]/u, "u") | ||||
|     .replace(/[ŸÿÝý]/u, "y") | ||||
|     .replace(/[^a-z0-9- ]/iu, "") | ||||
|     .trim() | ||||
|     .replace(/ /gi, "-") | ||||
|     .replace(/ /iu, "-") | ||||
|     .toLowerCase(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										314
									
								
								src/tailwind.css
									
									
									
									
									
								
							
							
						
						
									
										314
									
								
								src/tailwind.css
									
									
									
									
									
								
							| @ -2,167 +2,163 @@ | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
| 
 | ||||
| @layer base { | ||||
|   * { | ||||
|     @apply box-border font-body font-medium scroll-smooth scroll-m-8; | ||||
|   } | ||||
| 
 | ||||
|   h1, | ||||
|   h2, | ||||
|   h3, | ||||
|   h4, | ||||
|   h5, | ||||
|   h6 { | ||||
|     @apply font-headers font-black; | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|     @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark cursor-pointer; | ||||
|   } | ||||
| 
 | ||||
|   *::selection { | ||||
|     @apply bg-dark text-light; | ||||
|   } | ||||
| 
 | ||||
|   mark { | ||||
|     @apply bg-mid px-2; | ||||
|   } | ||||
| 
 | ||||
|   /* SCROLLBARS STYLING */ | ||||
| 
 | ||||
|   * { | ||||
|     @apply [scrollbar-color:theme(colors.dark)_transparent] [scrollbar-width:thin]; | ||||
|   } | ||||
| 
 | ||||
|   *::-webkit-scrollbar { | ||||
|     @apply w-3 mobile:w-0; | ||||
|   } | ||||
| 
 | ||||
|   *::-webkit-scrollbar-track { | ||||
|     @apply bg-light; | ||||
|   } | ||||
| 
 | ||||
|   *::-webkit-scrollbar-thumb { | ||||
|     @apply bg-dark rounded-full border-[3px] border-solid border-light; | ||||
|   } | ||||
| 
 | ||||
|   /* CHANGE FORMATTED DEFAULTS */ | ||||
| 
 | ||||
|   .formatted h1, | ||||
|   .formatted h2, | ||||
|   .formatted h3, | ||||
|   .formatted h4, | ||||
|   .formatted h5, | ||||
|   .formatted h6 { | ||||
|     @apply text-center flex gap-3 justify-center; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h1 { | ||||
|     @apply text-4xl my-16; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h1 + h2 { | ||||
|     @apply -mt-10; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h2 { | ||||
|     @apply text-3xl my-12; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h2 + h3 { | ||||
|     @apply -mt-8; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h3 { | ||||
|     @apply text-2xl my-8; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h3 + h4 { | ||||
|     @apply -mt-6; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h4 { | ||||
|     @apply text-xl my-6; | ||||
|   } | ||||
| 
 | ||||
|   .formatted h5 { | ||||
|     @apply text-lg my-4; | ||||
|   } | ||||
| 
 | ||||
|   .formatted p, | ||||
|   .formatted strong { | ||||
|     @apply my-2 text-justify; | ||||
|   } | ||||
| 
 | ||||
|   .formatted strong { | ||||
|     @apply font-black; | ||||
|   } | ||||
| 
 | ||||
|   .formatted footer { | ||||
|     @apply border-t-[3px] border-dotted pt-6; | ||||
|   } | ||||
| 
 | ||||
|   .formatted footer > div { | ||||
|     @apply my-2 px-6 py-4 rounded-xl; | ||||
|   } | ||||
| 
 | ||||
|   .formatted footer > div:target { | ||||
|     @apply bg-mid shadow-inner-sm shadow-shade; | ||||
|   } | ||||
| 
 | ||||
|   .formatted li::marker { | ||||
|     @apply text-dark; | ||||
|   } | ||||
| 
 | ||||
|   .formatted blockquote { | ||||
|     @apply border-l-dark; | ||||
|   } | ||||
| 
 | ||||
|   .formatted ul { | ||||
|     @apply list-disc pl-4; | ||||
|   } | ||||
| 
 | ||||
|   .formatted ol { | ||||
|     @apply list-decimal pl-4; | ||||
|   } | ||||
| 
 | ||||
|   .formatted blockquote { | ||||
|     @apply border-2 border-mid rounded-lg p-5 text-center my-8; | ||||
|   } | ||||
| 
 | ||||
|   .formatted blockquote cite { | ||||
|     @apply text-dark block; | ||||
|   } | ||||
| 
 | ||||
|   /* INPUT */ | ||||
| 
 | ||||
|   input, | ||||
|   textarea { | ||||
|     @apply rounded-full p-2 text-center bg-light outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent] text-dark hover:bg-mid transition-all placeholder:text-dark placeholder:opacity-60; | ||||
|   } | ||||
| 
 | ||||
|   input::placeholder { | ||||
|     @apply text-dark opacity-60; | ||||
|   } | ||||
| 
 | ||||
|   input:focus-visible, | ||||
|   textarea:focus-within { | ||||
|     @apply outline-none bg-mid shadow-inner-sm shadow-shade; | ||||
|   } | ||||
| 
 | ||||
|   textarea { | ||||
|     @apply rounded-2xl text-left p-6; | ||||
|   } | ||||
| 
 | ||||
|   input[type="submit"] { | ||||
|     @apply grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:text-light active:drop-shadow-black-lg active:border-black; | ||||
|   } | ||||
| * { | ||||
|   @apply box-border font-body font-medium scroll-smooth scroll-m-8; | ||||
| } | ||||
| 
 | ||||
| @layer components { | ||||
|   .texture-paper-dots { | ||||
|     @apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm]; | ||||
|   } | ||||
| h1, | ||||
| h2, | ||||
| h3, | ||||
| h4, | ||||
| h5, | ||||
| h6 { | ||||
|   @apply font-headers font-black; | ||||
| } | ||||
| 
 | ||||
| a { | ||||
|   @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark cursor-pointer; | ||||
| } | ||||
| 
 | ||||
| *::selection { | ||||
|   @apply bg-dark text-light; | ||||
| } | ||||
| 
 | ||||
| mark { | ||||
|   @apply bg-mid px-2; | ||||
| } | ||||
| 
 | ||||
| /* SCROLLBARS STYLING */ | ||||
| 
 | ||||
| * { | ||||
|   @apply [scrollbar-color:theme(colors.dark)_transparent] [scrollbar-width:thin]; | ||||
| } | ||||
| 
 | ||||
| *::-webkit-scrollbar { | ||||
|   @apply w-3 mobile:w-0; | ||||
| } | ||||
| 
 | ||||
| *::-webkit-scrollbar-track { | ||||
|   @apply bg-light; | ||||
| } | ||||
| 
 | ||||
| *::-webkit-scrollbar-thumb { | ||||
|   @apply bg-dark rounded-full border-[3px] border-solid border-light; | ||||
| } | ||||
| 
 | ||||
| /* CHANGE FORMATTED DEFAULTS */ | ||||
| 
 | ||||
| .formatted h1, | ||||
| .formatted h2, | ||||
| .formatted h3, | ||||
| .formatted h4, | ||||
| .formatted h5, | ||||
| .formatted h6 { | ||||
|   @apply text-center flex gap-3 justify-center; | ||||
| } | ||||
| 
 | ||||
| .formatted h1 { | ||||
|   @apply text-4xl my-16; | ||||
| } | ||||
| 
 | ||||
| .formatted h1 + h2 { | ||||
|   @apply -mt-10; | ||||
| } | ||||
| 
 | ||||
| .formatted h2 { | ||||
|   @apply text-3xl my-12; | ||||
| } | ||||
| 
 | ||||
| .formatted h2 + h3 { | ||||
|   @apply -mt-8; | ||||
| } | ||||
| 
 | ||||
| .formatted h3 { | ||||
|   @apply text-2xl my-8; | ||||
| } | ||||
| 
 | ||||
| .formatted h3 + h4 { | ||||
|   @apply -mt-6; | ||||
| } | ||||
| 
 | ||||
| .formatted h4 { | ||||
|   @apply text-xl my-6; | ||||
| } | ||||
| 
 | ||||
| .formatted h5 { | ||||
|   @apply text-lg my-4; | ||||
| } | ||||
| 
 | ||||
| .formatted p, | ||||
| .formatted strong { | ||||
|   @apply my-2 text-justify; | ||||
| } | ||||
| 
 | ||||
| .formatted strong { | ||||
|   @apply font-black; | ||||
| } | ||||
| 
 | ||||
| .formatted footer { | ||||
|   @apply border-t-[3px] border-dotted pt-6; | ||||
| } | ||||
| 
 | ||||
| .formatted footer > div { | ||||
|   @apply my-2 px-6 py-4 rounded-xl; | ||||
| } | ||||
| 
 | ||||
| .formatted footer > div:target { | ||||
|   @apply bg-mid shadow-inner-sm shadow-shade; | ||||
| } | ||||
| 
 | ||||
| .formatted li::marker { | ||||
|   @apply text-dark; | ||||
| } | ||||
| 
 | ||||
| .formatted blockquote { | ||||
|   @apply border-l-dark; | ||||
| } | ||||
| 
 | ||||
| .formatted ul { | ||||
|   @apply list-disc pl-4; | ||||
| } | ||||
| 
 | ||||
| .formatted ol { | ||||
|   @apply list-decimal pl-4; | ||||
| } | ||||
| 
 | ||||
| .formatted blockquote { | ||||
|   @apply border-2 border-mid rounded-lg p-5 text-center my-8; | ||||
| } | ||||
| 
 | ||||
| .formatted blockquote cite { | ||||
|   @apply text-dark block; | ||||
| } | ||||
| 
 | ||||
| /* INPUT */ | ||||
| 
 | ||||
| input, | ||||
| textarea { | ||||
|   @apply rounded-full p-2 text-center bg-light outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent] text-dark hover:bg-mid transition-all placeholder:text-dark placeholder:opacity-60; | ||||
| } | ||||
| 
 | ||||
| input::placeholder { | ||||
|   @apply text-dark opacity-60; | ||||
| } | ||||
| 
 | ||||
| input:focus-visible, | ||||
| textarea:focus-within { | ||||
|   @apply outline-none bg-mid shadow-inner-sm shadow-shade; | ||||
| } | ||||
| 
 | ||||
| textarea { | ||||
|   @apply rounded-2xl text-left p-6; | ||||
| } | ||||
| 
 | ||||
| input[type="submit"] { | ||||
|   @apply grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:text-light active:drop-shadow-black-lg active:border-black; | ||||
| } | ||||
| 
 | ||||
| .texture-paper-dots { | ||||
|   @apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm]; | ||||
| } | ||||
| 
 | ||||
| /* TIPPY */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint