Added Redux Toolkit to manage the UI globally

This commit is contained in:
DrMint 2022-02-20 14:59:56 +01:00
parent bcb9e5fd7d
commit 8731557f40
9 changed files with 383 additions and 87 deletions

231
package-lock.json generated
View File

@ -9,10 +9,12 @@
"@fontsource/material-icons-rounded": "^4.5.2", "@fontsource/material-icons-rounded": "^4.5.2",
"@fontsource/vollkorn": "^4.5.4", "@fontsource/vollkorn": "^4.5.4",
"@fontsource/zen-maru-gothic": "^4.5.4", "@fontsource/zen-maru-gothic": "^4.5.4",
"@reduxjs/toolkit": "^1.7.2",
"markdown-to-jsx": "^7.1.6", "markdown-to-jsx": "^7.1.6",
"next": "^12.1.0", "next": "^12.1.0",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-redux": "^7.2.6",
"react-swipeable": "^6.2.0", "react-swipeable": "^6.2.0",
"turndown": "^7.1.1" "turndown": "^7.1.1"
}, },
@ -133,7 +135,6 @@
"version": "7.17.2", "version": "7.17.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
"dev": true,
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
}, },
@ -437,6 +438,29 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@reduxjs/toolkit": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.2.tgz",
"integrity": "sha512-wwr3//Ar8ZhM9bS58O+HCIaMlR4Y6SNHfuszz9hKnQuFIKvwaL3Kmjo6fpDKUOjo4Lv54Yi299ed8rofCJ/Vjw==",
"dependencies": {
"immer": "^9.0.7",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1",
"reselect": "^4.1.5"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || 18.0.0-beta",
"react-redux": "^7.2.1 || ^8.0.0-beta"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@rushstack/eslint-patch": { "node_modules/@rushstack/eslint-patch": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
@ -457,6 +481,15 @@
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders" "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders"
} }
}, },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/json5": { "node_modules/@types/json5": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -478,25 +511,33 @@
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.4", "version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
"dev": true
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "17.0.39", "version": "17.0.39",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz",
"integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==",
"dev": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"node_modules/@types/react-redux": {
"version": "7.1.22",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.22.tgz",
"integrity": "sha512-GxIA1kM7ClU73I6wg9IRTVwSO9GS+SAKZKe0Enj+82HMU6aoESFU2HNAdNi3+J53IaOHPiUfT3kSG4L828joDQ==",
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"dev": true
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.12.0", "version": "5.12.0",
@ -1054,8 +1095,7 @@
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.0.10", "version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==", "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
"dev": true
}, },
"node_modules/damerau-levenshtein": { "node_modules/damerau-levenshtein": {
"version": "1.0.8", "version": "1.0.8",
@ -1978,6 +2018,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
@ -1987,6 +2035,15 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
"integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -2966,7 +3023,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -3042,8 +3098,36 @@
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true },
"node_modules/react-redux": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
"integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
"dependencies": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"peerDependencies": {
"react": "^16.8.3 || ^17"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}, },
"node_modules/react-swipeable": { "node_modules/react-swipeable": {
"version": "6.2.0", "version": "6.2.0",
@ -3065,11 +3149,26 @@
"node": ">=8.10.0" "node": ">=8.10.0"
} }
}, },
"node_modules/redux": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/regenerator-runtime": { "node_modules/regenerator-runtime": {
"version": "0.13.9", "version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"dev": true
}, },
"node_modules/regexp.prototype.flags": { "node_modules/regexp.prototype.flags": {
"version": "1.4.1", "version": "1.4.1",
@ -3099,6 +3198,11 @@
"url": "https://github.com/sponsors/mysticatea" "url": "https://github.com/sponsors/mysticatea"
} }
}, },
"node_modules/reselect": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
"integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.0", "version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@ -3725,7 +3829,6 @@
"version": "7.17.2", "version": "7.17.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
"dev": true,
"requires": { "requires": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
@ -3908,6 +4011,17 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@reduxjs/toolkit": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.2.tgz",
"integrity": "sha512-wwr3//Ar8ZhM9bS58O+HCIaMlR4Y6SNHfuszz9hKnQuFIKvwaL3Kmjo6fpDKUOjo4Lv54Yi299ed8rofCJ/Vjw==",
"requires": {
"immer": "^9.0.7",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1",
"reselect": "^4.1.5"
}
},
"@rushstack/eslint-patch": { "@rushstack/eslint-patch": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
@ -3925,6 +4039,15 @@
"lodash.merge": "^4.6.2" "lodash.merge": "^4.6.2"
} }
}, },
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/json5": { "@types/json5": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -3946,25 +4069,33 @@
"@types/prop-types": { "@types/prop-types": {
"version": "15.7.4", "version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
"dev": true
}, },
"@types/react": { "@types/react": {
"version": "17.0.39", "version": "17.0.39",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz",
"integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==",
"dev": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"@types/react-redux": {
"version": "7.1.22",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.22.tgz",
"integrity": "sha512-GxIA1kM7ClU73I6wg9IRTVwSO9GS+SAKZKe0Enj+82HMU6aoESFU2HNAdNi3+J53IaOHPiUfT3kSG4L828joDQ==",
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"dev": true
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.12.0", "version": "5.12.0",
@ -4340,8 +4471,7 @@
"csstype": { "csstype": {
"version": "3.0.10", "version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==", "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
"dev": true
}, },
"damerau-levenshtein": { "damerau-levenshtein": {
"version": "1.0.8", "version": "1.0.8",
@ -5048,12 +5178,25 @@
"has-symbols": "^1.0.2" "has-symbols": "^1.0.2"
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"ignore": { "ignore": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true "dev": true
}, },
"immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
"integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA=="
},
"import-fresh": { "import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -5734,7 +5877,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -5781,8 +5923,27 @@
"react-is": { "react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true },
"react-redux": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
"integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
"requires": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"dependencies": {
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}
}
}, },
"react-swipeable": { "react-swipeable": {
"version": "6.2.0", "version": "6.2.0",
@ -5799,11 +5960,24 @@
"picomatch": "^2.2.1" "picomatch": "^2.2.1"
} }
}, },
"redux": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
"requires": {}
},
"regenerator-runtime": { "regenerator-runtime": {
"version": "0.13.9", "version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"dev": true
}, },
"regexp.prototype.flags": { "regexp.prototype.flags": {
"version": "1.4.1", "version": "1.4.1",
@ -5821,6 +5995,11 @@
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true "dev": true
}, },
"reselect": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
"integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
},
"resolve": { "resolve": {
"version": "1.22.0", "version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",

View File

@ -12,10 +12,12 @@
"@fontsource/material-icons-rounded": "^4.5.2", "@fontsource/material-icons-rounded": "^4.5.2",
"@fontsource/vollkorn": "^4.5.4", "@fontsource/vollkorn": "^4.5.4",
"@fontsource/zen-maru-gothic": "^4.5.4", "@fontsource/zen-maru-gothic": "^4.5.4",
"@reduxjs/toolkit": "^1.7.2",
"markdown-to-jsx": "^7.1.6", "markdown-to-jsx": "^7.1.6",
"next": "^12.1.0", "next": "^12.1.0",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-redux": "^7.2.6",
"react-swipeable": "^6.2.0", "react-swipeable": "^6.2.0",
"turndown": "^7.1.1" "turndown": "^7.1.1"
}, },

View File

@ -1,12 +1,20 @@
import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import MainPanel from "./Panels/MainPanel"; import MainPanel from "./Panels/MainPanel";
import { useState } from "react";
import Head from "next/head"; import Head from "next/head";
import { useSwipeable } from "react-swipeable"; import { useSwipeable } from "react-swipeable";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Button from "components/Button"; import Button from "components/Button";
import { prettyLanguage } from "queries/helpers"; import { prettyLanguage } from "queries/helpers";
import { useMediaDesktop, useMediaMobile } from "hooks/useMediaQuery"; import { useMediaMobile } from "hooks/useMediaQuery";
import { useSelector, useDispatch } from "react-redux";
import {
setMainPanelOpen,
setLanguagePanelOpen,
setSubPanelOpen,
setMainPanelReduced,
} from "redux/AppLayoutSlice";
import { RootState } from "redux/store";
type AppLayoutProps = { type AppLayoutProps = {
subPanel?: React.ReactNode; subPanel?: React.ReactNode;
@ -20,53 +28,62 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
const titlePrefix = "Accords Library"; const titlePrefix = "Accords Library";
const router = useRouter(); const router = useRouter();
const [mainPanelOpen, setMainPanelOpen] = useState(false); const languagePanelOpen = useSelector(
const [subPanelOpen, setSubPanelOpen] = useState(false); (state: RootState) => state.appLayout.languagePanelOpen
const [languagePanelOpen, setLanguagePanelOpen] = useState(false); );
const [mainPanelReduced, setMainPanelReduced] = useState(false); const mainPanelOpen = useSelector(
(state: RootState) => state.appLayout.mainPanelOpen
);
const mainPanelReduced = useSelector(
(state: RootState) => state.appLayout.mainPanelReduced
);
const subPanelOpen = useSelector(
(state: RootState) => state.appLayout.subPanelOpen
);
const dispatch = useDispatch();
const isMobile = useMediaMobile(); const isMobile = useMediaMobile();
const isDesktop = useMediaDesktop();
const sensibilitySwipe = 1.1; const sensibilitySwipe = 1.1;
const handlers = useSwipeable({ const handlers = useSwipeable({
onSwipedLeft: (SwipeEventData) => { onSwipedLeft: (SwipeEventData) => {
if (SwipeEventData.velocity < sensibilitySwipe) return; if (SwipeEventData.velocity < sensibilitySwipe) return;
if (mainPanelOpen) { if (mainPanelOpen) {
setMainPanelOpen(false); dispatch(setMainPanelOpen(false));
} else if (props.subPanel && props.contentPanel) { } else if (props.subPanel && props.contentPanel) {
setSubPanelOpen(true); dispatch(setSubPanelOpen(true));
} }
}, },
onSwipedRight: (SwipeEventData) => { onSwipedRight: (SwipeEventData) => {
if (SwipeEventData.velocity < sensibilitySwipe) return; if (SwipeEventData.velocity < sensibilitySwipe) return;
if (subPanelOpen) { if (subPanelOpen) {
setSubPanelOpen(false); dispatch(setSubPanelOpen(false));
} else { } else {
setMainPanelOpen(true); dispatch(setMainPanelOpen(true));
} }
}, },
}); });
const mainPanelClass = `fixed desktop:left-0 desktop:top-0 desktop:bottom-0 transition-all ${ const mainPanelClass = `fixed desktop:left-0 desktop:top-0 desktop:bottom-0 ${
mainPanelReduced ? "desktop:w-[8rem]" : "desktop:w-[20rem]" mainPanelReduced ? "desktop:w-[8rem]" : "desktop:w-[20rem]"
}`; }`;
const subPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:w-[20rem] transition-all ${ const subPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:w-[20rem] ${
mainPanelReduced ? " desktop:left-[8rem]" : "desktop:left-[20rem]" mainPanelReduced ? " desktop:left-[8rem]" : "desktop:left-[20rem]"
}`; }`;
let contentPanelClass = ""; let contentPanelClass = "";
let turnSubIntoContent = false; if (props.subPanel) {
if (props.subPanel && props.contentPanel) { contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 transition-all ${
mainPanelReduced ? "desktop:left-[28rem]" : "desktop:left-[40rem]" mainPanelReduced ? "desktop:left-[28rem]" : "desktop:left-[40rem]"
}`; }`;
} else if (props.contentPanel) { } else if (props.contentPanel) {
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 transition-all ${ contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
mainPanelReduced ? "desktop:left-[8rem]" : "desktop:left-[20rem]" mainPanelReduced ? "desktop:left-[8rem]" : "desktop:left-[20rem]"
}`; }`;
} else if (props.subPanel) {
turnSubIntoContent = true;
} }
const turnSubIntoContent = props.subPanel && !props.contentPanel;
return ( return (
<div {...handlers} className="touch-pan-y"> <div {...handlers} className="touch-pan-y">
<Head> <Head>
@ -80,14 +97,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
<span <span
id="navbar-main-button" id="navbar-main-button"
className="material-icons mt-[.1em] cursor-pointer" className="material-icons mt-[.1em] cursor-pointer"
onClick={() => setMainPanelOpen(true)} onClick={() => dispatch(setMainPanelOpen(true))}
> >
menu menu
</span> </span>
<p className="text-2xl font-black font-headers">{props.title}</p> <p className="text-2xl font-black font-headers">{props.title}</p>
<span <span
className="material-icons mt-[.1em] cursor-pointer" className="material-icons mt-[.1em] cursor-pointer"
onClick={() => setSubPanelOpen(true)} onClick={() => dispatch(setSubPanelOpen(true))}
> >
{props.subPanel && !turnSubIntoContent {props.subPanel && !turnSubIntoContent
? props.subPanelIcon ? props.subPanelIcon
@ -98,14 +115,12 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
</div> </div>
{/* Content panel */} {/* Content panel */}
{props.contentPanel ? ( <div
<div className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm] ${contentPanelClass}`}
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm] ${contentPanelClass}`} >
> {props.contentPanel ? (
{props.contentPanel} props.contentPanel
</div> ) : (
) : (
<div className="top-0 left-0 right-0 bottom-20 overflow-y-scroll fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0 bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm]">
<div className="grid place-content-center h-full"> <div className="grid place-content-center h-full">
<div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40"> <div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40">
<p className="text-4xl"></p> <p className="text-4xl"></p>
@ -114,8 +129,8 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
</p> </p>
</div> </div>
</div> </div>
</div> )}
)} </div>
{/* Background when navbar is opened */} {/* Background when navbar is opened */}
<div <div
@ -127,8 +142,8 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
: "opacity-0 pointer-events-none touch-none" : "opacity-0 pointer-events-none touch-none"
}`} }`}
onClick={() => { onClick={() => {
setMainPanelOpen(false); dispatch(setMainPanelOpen(false));
setSubPanelOpen(false); dispatch(setSubPanelOpen(false));
}} }}
></div> ></div>
@ -155,11 +170,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm] className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm]
${mainPanelOpen ? "" : "mobile:-translate-x-full"}`} ${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
> >
<MainPanel <MainPanel langui={props.langui} />
langui={props.langui}
setLanguagePanelOpen={setLanguagePanelOpen}
reduced={mainPanelReduced && isDesktop}
/>
</div> </div>
{/* Main panel minimize button*/} {/* Main panel minimize button*/}
@ -167,7 +178,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
className={`mobile:hidden translate-x-0 fixed top-1/2 z-20 ${ className={`mobile:hidden translate-x-0 fixed top-1/2 z-20 ${
mainPanelReduced ? "left-[6.65rem]" : "left-[18.65rem]" mainPanelReduced ? "left-[6.65rem]" : "left-[18.65rem]"
}`} }`}
onClick={() => setMainPanelReduced(!mainPanelReduced)} onClick={() => dispatch(setMainPanelReduced(!mainPanelReduced))}
> >
<Button className="material-icons bg-light !px-2"> <Button className="material-icons bg-light !px-2">
{mainPanelReduced ? "chevron_right" : "chevron_left"} {mainPanelReduced ? "chevron_right" : "chevron_left"}
@ -182,7 +193,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
: "bg-opacity-0 pointer-events-none touch-none" : "bg-opacity-0 pointer-events-none touch-none"
}`} }`}
onClick={() => { onClick={() => {
setLanguagePanelOpen(false); dispatch(setLanguagePanelOpen(false));
}} }}
> >
<div <div

View File

@ -1,5 +1,6 @@
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Link from "next/link"; import Link from "next/link";
import { MouseEventHandler } from "react";
type NavOptionProps = { type NavOptionProps = {
url: string; url: string;
@ -8,6 +9,7 @@ type NavOptionProps = {
subtitle?: string; subtitle?: string;
border?: boolean; border?: boolean;
reduced?: boolean; reduced?: boolean;
onClick?: MouseEventHandler<HTMLDivElement>;
}; };
export default function NavOption(props: NavOptionProps): JSX.Element { export default function NavOption(props: NavOptionProps): JSX.Element {
@ -24,15 +26,20 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
if (props.reduced) { if (props.reduced) {
return ( return (
<Link href={props.url} passHref> <Link href={props.url} passHref>
<div className={`grid ${divCommon}`}> <div onClick={props.onClick} className={`grid ${divCommon}`}>
<span className="place-self-center material-icons mt-[.1em]">{props.icon}</span> <span className="place-self-center material-icons mt-[.1em]">
{props.icon}
</span>
</div> </div>
</Link> </Link>
); );
} else { } else {
return ( return (
<Link href={props.url} passHref> <Link href={props.url} passHref>
<div className={`grid grid-cols-[auto_1fr] text-left ${divCommon}`}> <div
onClick={props.onClick}
className={`grid grid-cols-[auto_1fr] text-left ${divCommon}`}
>
<span className="material-icons mt-[.1em]">{props.icon}</span> <span className="material-icons mt-[.1em]">{props.icon}</span>
<h3 className="text-2xl">{props.title}</h3> <h3 className="text-2xl">{props.title}</h3>
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>} {props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
@ -43,7 +50,10 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
} else { } else {
return ( return (
<Link href={props.url} passHref> <Link href={props.url} passHref>
<div className={`grid text-center ${divCommon}`}> <div
onClick={props.onClick}
className={`grid text-center ${divCommon}`}
>
<h3 className="text-2xl">{props.title}</h3> <h3 className="text-2xl">{props.title}</h3>
{props.subtitle && <p>{props.subtitle}</p>} {props.subtitle && <p>{props.subtitle}</p>}
</div> </div>

View File

@ -6,24 +6,32 @@ import Button from "components/Button";
import HorizontalLine from "components/HorizontalLine"; import HorizontalLine from "components/HorizontalLine";
import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import Markdown from "markdown-to-jsx"; import Markdown from "markdown-to-jsx";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "redux/store";
import { setLanguagePanelOpen, setMainPanelOpen } from "redux/AppLayoutSlice";
import { useMediaDesktop } from "hooks/useMediaQuery";
type MainPanelProps = { type MainPanelProps = {
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
setLanguagePanelOpen: Function;
reduced: boolean;
}; };
export default function MainPanel(props: MainPanelProps): JSX.Element { export default function MainPanel(props: MainPanelProps): JSX.Element {
const langui = props.langui; const langui = props.langui;
const router = useRouter(); const router = useRouter();
const reduced = props.reduced; const isDesktop = useMediaDesktop();
const mainPanelReduced = useSelector(
(state: RootState) => state.appLayout.mainPanelReduced
);
const dispatch = useDispatch();
return ( return (
<div <div
id="mainPanel" id="mainPanel"
className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center" className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center"
> >
{reduced ? ( {mainPanelReduced && isDesktop ? (
<div className="grid place-items-center gap-4"> <div className="grid place-items-center gap-4">
<Link href="/" passHref> <Link href="/" passHref>
<div className="w-8 cursor-pointer transition-[filter] hover:colorize-dark"> <div className="w-8 cursor-pointer transition-[filter] hover:colorize-dark">
@ -34,7 +42,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
</div> </div>
</Link> </Link>
{router.locale ? ( {router.locale ? (
<div onClick={() => props.setLanguagePanelOpen(true)}> <div onClick={() => dispatch(setLanguagePanelOpen(true))}>
<Button className="text-xs">{router.locale.toUpperCase()}</Button> <Button className="text-xs">{router.locale.toUpperCase()}</Button>
</div> </div>
) : ( ) : (
@ -54,7 +62,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
</Link> </Link>
<div <div
className="relative mt-5" className="relative mt-5"
onClick={() => props.setLanguagePanelOpen(true)} onClick={() => dispatch(setLanguagePanelOpen(true))}
> >
{router.locale ? ( {router.locale ? (
<Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5"> <Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5">
@ -76,7 +84,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
icon="library_books" icon="library_books"
title={langui.main_library} title={langui.main_library}
subtitle={langui.main_library_description} subtitle={langui.main_library_description}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
@ -84,7 +93,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
icon="travel_explore" icon="travel_explore"
title={langui.main_wiki} title={langui.main_wiki}
subtitle={langui.main_wiki_description} subtitle={langui.main_wiki_description}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
@ -92,7 +102,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
icon="watch_later" icon="watch_later"
title={langui.main_chronicles} title={langui.main_chronicles}
subtitle={langui.main_chronicles_description} subtitle={langui.main_chronicles_description}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<HorizontalLine /> <HorizontalLine />
@ -101,40 +112,49 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
url="/news" url="/news"
icon="feed" icon="feed"
title={langui.main_news} title={langui.main_news}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
url="/merch" url="/merch"
icon="store" icon="store"
title={langui.main_merch} title={langui.main_merch}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
url="/gallery" url="/gallery"
icon="collections" icon="collections"
title={langui.main_gallery} title={langui.main_gallery}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
url="/archives" url="/archives"
icon="inventory" icon="inventory"
title={langui.main_archives} title={langui.main_archives}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
<NavOption <NavOption
url="/about-us" url="/about-us"
icon="info" icon="info"
title={langui.main_about_us} title={langui.main_about_us}
reduced={reduced} reduced={mainPanelReduced && isDesktop}
onClick={() => dispatch(setMainPanelOpen(false))}
/> />
{reduced ? "" : <HorizontalLine />} {mainPanelReduced && isDesktop ? "" : <HorizontalLine />}
<div className={`text-center ${reduced ? "hidden" : ""}`}> <div
className={`text-center ${
mainPanelReduced && isDesktop ? "hidden" : ""
}`}
>
<p> <p>
{langui.main_licensing ? ( {langui.main_licensing ? (
<Markdown>{langui.main_licensing}</Markdown> <Markdown>{langui.main_licensing}</Markdown>

View File

@ -4,6 +4,13 @@ import "@fontsource/zen-maru-gothic/500.css";
import "@fontsource/vollkorn/700.css"; import "@fontsource/vollkorn/700.css";
import "@fontsource/material-icons"; import "@fontsource/material-icons";
import { store } from "redux/store";
import { Provider } from "react-redux";
export default function AccordsLibraryApp(appProps: AppProps) { export default function AccordsLibraryApp(appProps: AppProps) {
return <appProps.Component {...appProps.pageProps} />; return (
<Provider store={store}>
<appProps.Component {...appProps.pageProps} />
</Provider>
);
} }

View File

@ -34,6 +34,8 @@ import HorizontalLine from "components/HorizontalLine";
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
import InsetBox from "components/InsetBox"; import InsetBox from "components/InsetBox";
import { setSubPanelOpen } from "redux/AppLayoutSlice";
import { useDispatch } from "react-redux";
type LibrarySlugProps = { type LibrarySlugProps = {
libraryItem: GetLibraryItemQuery; libraryItem: GetLibraryItemQuery;
@ -43,6 +45,8 @@ type LibrarySlugProps = {
export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
const item = props.libraryItem.libraryItems.data[0].attributes; const item = props.libraryItem.libraryItems.data[0].attributes;
const langui = props.langui.websiteInterfaces.data[0].attributes; const langui = props.langui.websiteInterfaces.data[0].attributes;
const dispatch = useDispatch();
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ReturnButton <ReturnButton
@ -57,6 +61,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
title={langui.library_item_summary} title={langui.library_item_summary}
url="#summary" url="#summary"
border={true} border={true}
onClick={() => dispatch(setSubPanelOpen(false))}
/> />
{item.gallery.data.length > 0 ? ( {item.gallery.data.length > 0 ? (
@ -64,6 +69,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
title={langui.library_item_gallery} title={langui.library_item_gallery}
url="#gallery" url="#gallery"
border={true} border={true}
onClick={() => dispatch(setSubPanelOpen(false))}
/> />
) : ( ) : (
"" ""
@ -73,6 +79,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
title={langui.library_item_details} title={langui.library_item_details}
url="#details" url="#details"
border={true} border={true}
onClick={() => dispatch(setSubPanelOpen(false))}
/> />
{item.subitems.data.length > 0 ? ( {item.subitems.data.length > 0 ? (
@ -83,12 +90,14 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
title={langui.library_item_variants} title={langui.library_item_variants}
url="#variants" url="#variants"
border={true} border={true}
onClick={() => dispatch(setSubPanelOpen(false))}
/> />
) : ( ) : (
<NavOption <NavOption
title={langui.library_item_subitems} title={langui.library_item_subitems}
url="#subitems" url="#subitems"
border={true} border={true}
onClick={() => dispatch(setSubPanelOpen(false))}
/> />
) )
) : ( ) : (

View File

@ -0,0 +1,47 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface AppLayoutState {
subPanelOpen: boolean;
languagePanelOpen: boolean;
mainPanelReduced: boolean;
mainPanelOpen: boolean;
}
const initialState: AppLayoutState = {
subPanelOpen: false,
languagePanelOpen: false,
mainPanelReduced: false,
mainPanelOpen: false,
};
export const appLayoutSlice = createSlice({
name: "appLayout",
initialState,
reducers: {
setMainPanelOpen: (state, action: PayloadAction<boolean>) => {
state.mainPanelOpen = action.payload;
},
setLanguagePanelOpen: (state, action: PayloadAction<boolean>) => {
state.languagePanelOpen = action.payload;
},
setSubPanelOpen: (state, action: PayloadAction<boolean>) => {
state.subPanelOpen = action.payload;
},
setMainPanelReduced: (state, action: PayloadAction<boolean>) => {
state.mainPanelReduced = action.payload;
},
},
});
// Action creators are generated for each case reducer function
export const {
setMainPanelOpen,
setLanguagePanelOpen,
setSubPanelOpen,
setMainPanelReduced,
} = appLayoutSlice.actions;
export default appLayoutSlice.reducer;

11
src/redux/store.ts Normal file
View File

@ -0,0 +1,11 @@
import { configureStore } from "@reduxjs/toolkit";
import appLayoutReducer from "redux/AppLayoutSlice";
export const store = configureStore({
reducer: { appLayout: appLayoutReducer },
});
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;