MAJ PAGES SERVICES
This commit is contained in:
Generated
+138
-6
@@ -17,6 +17,7 @@
|
|||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-helmet-async": "^2.0.5",
|
"react-helmet-async": "^2.0.5",
|
||||||
|
"react-quill": "^2.0.0",
|
||||||
"react-router-dom": "^7.1.1",
|
"react-router-dom": "^7.1.1",
|
||||||
"react-simple-lightbox": "^1.0.26",
|
"react-simple-lightbox": "^1.0.26",
|
||||||
"react-toastify": "^11.0.3",
|
"react-toastify": "^11.0.3",
|
||||||
@@ -1788,6 +1789,15 @@
|
|||||||
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/quill": {
|
||||||
|
"version": "1.3.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
|
||||||
|
"integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"parchment": "^1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.3.18",
|
"version": "18.3.18",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
||||||
@@ -4274,6 +4284,26 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/deep-equal": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-arguments": "^1.1.1",
|
||||||
|
"is-date-object": "^1.0.5",
|
||||||
|
"is-regex": "^1.1.4",
|
||||||
|
"object-is": "^1.1.5",
|
||||||
|
"object-keys": "^1.1.1",
|
||||||
|
"regexp.prototype.flags": "^1.5.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/deep-is": {
|
"node_modules/deep-is": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
@@ -5062,6 +5092,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/events": {
|
"node_modules/events": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
@@ -5167,6 +5203,12 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/extend-shallow": {
|
"node_modules/extend-shallow": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||||
@@ -5243,6 +5285,12 @@
|
|||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-diff": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/fast-json-stable-stringify": {
|
"node_modules/fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
@@ -5539,7 +5587,6 @@
|
|||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
||||||
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
|
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
@@ -5778,7 +5825,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-symbols": "^1.0.3"
|
"has-symbols": "^1.0.3"
|
||||||
@@ -6199,6 +6245,22 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-arguments": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"has-tostringtag": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-array-buffer": {
|
"node_modules/is-array-buffer": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||||
@@ -6358,7 +6420,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
||||||
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -6548,7 +6609,6 @@
|
|||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||||
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -7726,6 +7786,22 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-is": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.7",
|
||||||
|
"define-properties": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-keys": {
|
"node_modules/object-keys": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||||
@@ -7944,6 +8020,12 @@
|
|||||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||||
"license": "(MIT AND Zlib)"
|
"license": "(MIT AND Zlib)"
|
||||||
},
|
},
|
||||||
|
"node_modules/parchment": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -9823,6 +9905,43 @@
|
|||||||
"node": ">=0.4.x"
|
"node": ">=0.4.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/quill": {
|
||||||
|
"version": "1.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
|
||||||
|
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"clone": "^2.1.1",
|
||||||
|
"deep-equal": "^1.0.1",
|
||||||
|
"eventemitter3": "^2.0.3",
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"parchment": "^1.1.4",
|
||||||
|
"quill-delta": "^3.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/quill-delta": {
|
||||||
|
"version": "3.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
|
||||||
|
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"deep-equal": "^1.0.1",
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"fast-diff": "1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/quill/node_modules/clone": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/randombytes": {
|
"node_modules/randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
@@ -9908,6 +10027,21 @@
|
|||||||
"integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
|
"integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-quill": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/quill": "^1.3.10",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
|
"quill": "^1.3.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16 || ^17 || ^18",
|
||||||
|
"react-dom": "^16 || ^17 || ^18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "7.1.4",
|
"version": "7.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.4.tgz",
|
||||||
@@ -10275,7 +10409,6 @@
|
|||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
||||||
"integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
|
"integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
@@ -10695,7 +10828,6 @@
|
|||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
||||||
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.4",
|
"define-data-property": "^1.1.4",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-helmet-async": "^2.0.5",
|
"react-helmet-async": "^2.0.5",
|
||||||
|
"react-quill": "^2.0.0",
|
||||||
"react-router-dom": "^7.1.1",
|
"react-router-dom": "^7.1.1",
|
||||||
"react-simple-lightbox": "^1.0.26",
|
"react-simple-lightbox": "^1.0.26",
|
||||||
"react-toastify": "^11.0.3",
|
"react-toastify": "^11.0.3",
|
||||||
|
|||||||
@@ -197,6 +197,15 @@ const Header = () => {
|
|||||||
Systeme Sécurité Incendie (SSI)
|
Systeme Sécurité Incendie (SSI)
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
|
<MenuItem
|
||||||
|
component={Link}
|
||||||
|
to="/services/expertises-tce"
|
||||||
|
onClick={handleMenuClose}
|
||||||
|
>
|
||||||
|
<WorkIcon sx={{ marginRight: 1}} />
|
||||||
|
expertises-tce
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -397,6 +406,18 @@ const Header = () => {
|
|||||||
<ListItemText primary="SSI..." />
|
<ListItemText primary="SSI..." />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
component={Link}
|
||||||
|
to="/services/expertises-tce"
|
||||||
|
selected={location.pathname.includes(
|
||||||
|
"/services/expertises-tce"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<WorkIcon sx={{ marginRight: 0.5 }} />
|
||||||
|
<ListItemText primary="Expertises-tce" />
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
<ListItem
|
<ListItem
|
||||||
button
|
button
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Paper,
|
Paper,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
|
Grid,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Add, Delete, ArrowBack, Save } from "@mui/icons-material";
|
import { Add, Delete, ArrowBack, Save } from "@mui/icons-material";
|
||||||
|
import ReactQuill from "react-quill";
|
||||||
|
import "react-quill/dist/quill.snow.css"; // Import du style de l'éditeur
|
||||||
|
|
||||||
function EditPageACF() {
|
function EditPageACF() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -21,14 +24,14 @@ function EditPageACF() {
|
|||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [successMessage, setSuccessMessage] = useState("");
|
const [successMessage, setSuccessMessage] = useState("");
|
||||||
|
|
||||||
// ✅ Vérifier l'authentification
|
// ✅ Vérification de l'authentification
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!getToken()) {
|
if (!getToken()) {
|
||||||
navigate("/admin/login");
|
navigate("/admin/login");
|
||||||
}
|
}
|
||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
// ✅ Récupérer les champs ACF de la page
|
// ✅ Récupération des champs ACF de la page
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchPage = async () => {
|
const fetchPage = async () => {
|
||||||
console.log("📢 Récupération de la page avec ID :", id);
|
console.log("📢 Récupération de la page avec ID :", id);
|
||||||
@@ -41,13 +44,11 @@ function EditPageACF() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const pageData = await getPageById(id);
|
const pageData = await getPageById(id);
|
||||||
|
|
||||||
if (!pageData || !pageData.acf) {
|
if (!pageData || !pageData.acf) {
|
||||||
setError("❌ Impossible de charger les champs ACF.");
|
setError("❌ Impossible de charger les champs ACF.");
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAcfFields(pageData.acf);
|
setAcfFields(pageData.acf);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -62,7 +63,6 @@ function EditPageACF() {
|
|||||||
// ✅ Mise à jour des champs ACF
|
// ✅ Mise à jour des champs ACF
|
||||||
const handleUpdateACF = async (e) => {
|
const handleUpdateACF = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updatePageACF(id, acfFields);
|
await updatePageACF(id, acfFields);
|
||||||
setSuccessMessage("✅ Modifications enregistrées !");
|
setSuccessMessage("✅ Modifications enregistrées !");
|
||||||
@@ -73,7 +73,7 @@ function EditPageACF() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ Gérer la modification des champs ACF
|
// ✅ Gestion des champs ACF
|
||||||
const handleFieldChange = (field, value) => {
|
const handleFieldChange = (field, value) => {
|
||||||
setAcfFields((prevFields) => ({
|
setAcfFields((prevFields) => ({
|
||||||
...prevFields,
|
...prevFields,
|
||||||
@@ -81,7 +81,7 @@ function EditPageACF() {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ Gérer la FAQ : ajouter, modifier et supprimer des entrées
|
// ✅ Gestion des champs FAQ
|
||||||
const handleFAQChange = (index, field, value) => {
|
const handleFAQChange = (index, field, value) => {
|
||||||
const updatedFAQ = [...(acfFields.faq?.faq_list || [])];
|
const updatedFAQ = [...(acfFields.faq?.faq_list || [])];
|
||||||
updatedFAQ[index][field] = value;
|
updatedFAQ[index][field] = value;
|
||||||
@@ -104,12 +104,9 @@ function EditPageACF() {
|
|||||||
const deleteFAQ = (index) => {
|
const deleteFAQ = (index) => {
|
||||||
const updatedFAQList = acfFields.faq.faq_list.filter((_, i) => i !== index);
|
const updatedFAQList = acfFields.faq.faq_list.filter((_, i) => i !== index);
|
||||||
const updatedACF = { ...acfFields, faq: { ...acfFields.faq, faq_list: updatedFAQList } };
|
const updatedACF = { ...acfFields, faq: { ...acfFields.faq, faq_list: updatedFAQList } };
|
||||||
|
|
||||||
// Si la FAQ devient vide, on la supprime entièrement pour éviter l'affichage
|
|
||||||
if (updatedFAQList.length === 0) {
|
if (updatedFAQList.length === 0) {
|
||||||
delete updatedACF.faq.faq_list;
|
delete updatedACF.faq.faq_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAcfFields(updatedACF);
|
setAcfFields(updatedACF);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -127,7 +124,7 @@ function EditPageACF() {
|
|||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Container maxWidth="sm">
|
<Container maxWidth="md">
|
||||||
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, mt: 10 }}>
|
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, mt: 10 }}>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<ArrowBack />}
|
startIcon={<ArrowBack />}
|
||||||
@@ -148,43 +145,49 @@ function EditPageACF() {
|
|||||||
|
|
||||||
<form onSubmit={handleUpdateACF}>
|
<form onSubmit={handleUpdateACF}>
|
||||||
{/* ✅ Affichage dynamique des champs ACF sauf la FAQ */}
|
{/* ✅ Affichage dynamique des champs ACF sauf la FAQ */}
|
||||||
|
<Grid container spacing={2}>
|
||||||
{Object.keys(acfFields)
|
{Object.keys(acfFields)
|
||||||
.filter((field) => field !== "faq" && field !== "faq_list") // 🔥 On exclut la FAQ et faq_list
|
.filter((field) => field !== "faq" && field !== "faq_list")
|
||||||
.map((field) => (
|
.map((field) => (
|
||||||
|
<Grid item xs={12} md={6} key={field}>
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
|
||||||
|
{field.replace(/_/g, " ")}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{/* Utiliser l'éditeur WYSIWYG pour les champs texte enrichi */}
|
||||||
|
{field.includes("content") || field.includes("description") ? (
|
||||||
|
<ReactQuill
|
||||||
|
theme="snow"
|
||||||
|
value={acfFields[field] || ""}
|
||||||
|
onChange={(value) => handleFieldChange(field, value)}
|
||||||
|
style={{ backgroundColor: "#fff", borderRadius: "5px", marginBottom: "16px" }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<TextField
|
<TextField
|
||||||
key={field}
|
|
||||||
label={field.replace(/_/g, " ")}
|
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={acfFields[field] || ""}
|
value={acfFields[field] || ""}
|
||||||
onChange={(e) => handleFieldChange(field, e.target.value)}
|
onChange={(e) => handleFieldChange(field, e.target.value)}
|
||||||
sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }}
|
sx={{ backgroundColor: "#fff", borderRadius: "5px" }}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
))}
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* ✅ Gestion de la FAQ uniquement si elle est définie */}
|
{/* ✅ Gestion de la FAQ uniquement si elle est définie */}
|
||||||
{acfFields.faq?.faq_list && acfFields.faq.faq_list.length > 0 && (
|
{acfFields.faq?.faq_list && acfFields.faq.faq_list.length > 0 && (
|
||||||
<Box sx={{ mb: 3 }}>
|
<Box sx={{ mt: 4 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>FAQ</Typography>
|
<Typography variant="h5" sx={{ fontWeight: "bold", mb: 2 }}>📌 FAQ</Typography>
|
||||||
{acfFields.faq.faq_list.map((item, index) => (
|
{acfFields.faq.faq_list.map((item, index) => (
|
||||||
<Box
|
<Paper key={index} sx={{ padding: 2, mb: 2 }}>
|
||||||
key={index}
|
|
||||||
sx={{
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
padding: 2,
|
|
||||||
borderRadius: 2,
|
|
||||||
mb: 2,
|
|
||||||
position: "relative",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextField
|
<TextField
|
||||||
label="Question"
|
label="Question"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={item.question || ""}
|
value={item.question || ""}
|
||||||
onChange={(e) => handleFAQChange(index, "question", e.target.value)}
|
onChange={(e) => handleFAQChange(index, "question", e.target.value)}
|
||||||
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
|
sx={{ mb: 1 }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Réponse"
|
label="Réponse"
|
||||||
@@ -194,26 +197,24 @@ function EditPageACF() {
|
|||||||
rows={3}
|
rows={3}
|
||||||
value={item.answer || ""}
|
value={item.answer || ""}
|
||||||
onChange={(e) => handleFAQChange(index, "answer", e.target.value)}
|
onChange={(e) => handleFAQChange(index, "answer", e.target.value)}
|
||||||
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<Delete />}
|
startIcon={<Delete />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="error"
|
color="error"
|
||||||
onClick={() => deleteFAQ(index)}
|
onClick={() => deleteFAQ(index)}
|
||||||
sx={{ position: "absolute", top: 10, right: 10 }}
|
sx={{ mt: 1 }}
|
||||||
>
|
>
|
||||||
Supprimer
|
Supprimer
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Paper>
|
||||||
))}
|
))}
|
||||||
<Button startIcon={<Add />} variant="contained" color="primary" onClick={addFAQ} sx={{ mb: 2 }}>
|
<Button startIcon={<Add />} variant="contained" color="primary" onClick={addFAQ}>
|
||||||
Ajouter une question
|
Ajouter une question
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
<Button type="submit" variant="contained" color="primary" fullWidth startIcon={<Save />} sx={{ mt: 3 }}>
|
<Button type="submit" variant="contained" color="primary" fullWidth startIcon={<Save />} sx={{ mt: 3 }}>
|
||||||
Enregistrer les modifications
|
Enregistrer les modifications
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import ServicePageTemplate from "../ServicePageTemplate";
|
||||||
|
import { getPageById } from "../../wordpress";
|
||||||
|
|
||||||
|
const ServiceCinq = () => {
|
||||||
|
const [acfData, setAcfData] = useState(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const pageId = 612; // 🔥 Remplace par l'ID réel de la page WordPress
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchACFData = async () => {
|
||||||
|
try {
|
||||||
|
const pageData = await getPageById(pageId);
|
||||||
|
setAcfData(pageData.acf);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("❌ Erreur récupération des champs ACF :", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchACFData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// ✅ Affichage du chargement en attendant les données ACF
|
||||||
|
if (loading) {
|
||||||
|
return <p>Chargement...</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceDetails = {
|
||||||
|
// Hero
|
||||||
|
title: acfData?.titre_principal_tce || "Titre héros !", // ✅ Modifiable individuellement
|
||||||
|
subtitle: acfData?.description_principal_tce || "Description, héros", // ✅ Modifiable individuellement
|
||||||
|
|
||||||
|
image: "https://picsum.photos/id/1021/1920/1080.webp",
|
||||||
|
ctaText: "En savoir plus",
|
||||||
|
ctaLink: "/contact",
|
||||||
|
|
||||||
|
// section 1
|
||||||
|
interestTitle: acfData?.second_titre_tce || "Titre interet", // ✅ Modifiable individuellement
|
||||||
|
description: acfData?.second_description_tce || "Description interet", // ✅ Modifiable individuellement
|
||||||
|
|
||||||
|
// section 2
|
||||||
|
desirTitle: "Titre", // ✅ Modifiable individuellement
|
||||||
|
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
title: "Titre",
|
||||||
|
description: "Description.",
|
||||||
|
modalText: "Description Modal.",
|
||||||
|
modalImage: "https://picsum.photos/id/300/800/400.webp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Titre",
|
||||||
|
description: "Description.",
|
||||||
|
modalText: "Description Modal.",
|
||||||
|
modalImage: "https://picsum.photos/id/301/800/400.webp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Titre",
|
||||||
|
description: "Description.",
|
||||||
|
modalText: "Description Modal.",
|
||||||
|
modalImage: "https://picsum.photos/id/302/800/400.webp",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
carouselItems: [
|
||||||
|
{
|
||||||
|
title: "Portfolio Modern",
|
||||||
|
description: "Montrez vos compétences avec un portfolio unique.",
|
||||||
|
image: "https://picsum.photos/id/305/800/400.webp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Blog SEO",
|
||||||
|
description: "Optimisez vos articles pour le référencement.",
|
||||||
|
image: "https://picsum.photos/id/306/800/400.webp",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return <ServicePageTemplate {...serviceDetails} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServiceCinq;
|
||||||
@@ -30,7 +30,7 @@ const ServiceQuatre = () => {
|
|||||||
const serviceDetails = {
|
const serviceDetails = {
|
||||||
// Hero
|
// Hero
|
||||||
title: acfData?.titre_principal || "Titre héros !", // ✅ Modifiable individuellement
|
title: acfData?.titre_principal || "Titre héros !", // ✅ Modifiable individuellement
|
||||||
subtitle: acfData?.description_principal || "Description, héros", // ✅ Modifiable individuellement
|
subtitle: <span dangerouslySetInnerHTML={{ __html: acfData?.description_principal || "Description, héros" }} />,
|
||||||
|
|
||||||
image: "https://picsum.photos/id/1021/1920/1080.webp",
|
image: "https://picsum.photos/id/1021/1920/1080.webp",
|
||||||
ctaText: "En savoir plus",
|
ctaText: "En savoir plus",
|
||||||
@@ -38,28 +38,27 @@ const ServiceQuatre = () => {
|
|||||||
|
|
||||||
// section 1
|
// section 1
|
||||||
interestTitle: acfData?.second_titre || "Titre interet", // ✅ Modifiable individuellement
|
interestTitle: acfData?.second_titre || "Titre interet", // ✅ Modifiable individuellement
|
||||||
description: acfData?.second_description || "Description interet", // ✅ Modifiable individuellement
|
description: <span dangerouslySetInnerHTML={{ __html: acfData?.second_description || "Description interet" }} />,
|
||||||
|
|
||||||
// section 2
|
// section 2
|
||||||
desirTitle: "Titre", // ✅ Modifiable individuellement
|
desirTitle: "Titre", // ✅ Modifiable individuellement
|
||||||
|
|
||||||
features: [
|
features: [
|
||||||
{
|
{
|
||||||
title: "Titre",
|
title: acfData?.titre_carte_one || "Titre !",
|
||||||
description: "Description.",
|
description: acfData?.description_carte_one || "Description.",
|
||||||
modalText: "Description Modal.",
|
modalText: acfData?.description_carte_one || "Description Modal.",
|
||||||
modalImage: "https://picsum.photos/id/300/800/400.webp",
|
modalImage: "https://picsum.photos/id/300/800/400.webp",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Titre",
|
title: acfData?.titre_carte_two || "Titre !",
|
||||||
description: "Description.",
|
description: acfData?.description_carte_two || "Description.",
|
||||||
modalText: "Description Modal.",
|
modalText: acfData?.description_carte_two || "Description Modal.",
|
||||||
modalImage: "https://picsum.photos/id/301/800/400.webp",
|
modalImage: "https://picsum.photos/id/301/800/400.webp",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Titre",
|
title: acfData?.titre_carte_tree || "Titre !",
|
||||||
description: "Description.",
|
description: acfData?.description_carte_tree || "Description.",
|
||||||
modalText: "Description Modal.",
|
modalText: acfData?.description_carte_tree || "Description Modal.",
|
||||||
modalImage: "https://picsum.photos/id/302/800/400.webp",
|
modalImage: "https://picsum.photos/id/302/800/400.webp",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Box, Typography, Button, Grid, Card, CardContent, Modal, Fade, Backdrop, CircularProgress } from "@mui/material";
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
Modal,
|
||||||
|
Fade,
|
||||||
|
Backdrop,
|
||||||
|
CircularProgress,
|
||||||
|
} from "@mui/material";
|
||||||
import { Swiper, SwiperSlide } from "swiper/react";
|
import { Swiper, SwiperSlide } from "swiper/react";
|
||||||
import { Navigation, Pagination, Autoplay } from "swiper/modules";
|
import { Navigation, Pagination, Autoplay } from "swiper/modules";
|
||||||
import "swiper/css";
|
import "swiper/css";
|
||||||
@@ -40,7 +51,13 @@ const ServicePageTemplate = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ backgroundColor: "#f5f5f5", color: "#333", fontFamily: "Arial, sans-serif" }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
backgroundColor: "#f5f5f5",
|
||||||
|
color: "#333",
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{/* ✅ SEO META TAGS */}
|
{/* ✅ SEO META TAGS */}
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{seo?.metaTitle || title}</title>
|
<title>{seo?.metaTitle || title}</title>
|
||||||
@@ -72,13 +89,27 @@ const ServicePageTemplate = ({
|
|||||||
padding: "20px",
|
padding: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{
|
<Box
|
||||||
|
sx={{
|
||||||
maxWidth: "800px",
|
maxWidth: "800px",
|
||||||
backgroundColor: "rgba(255, 255, 255, 0.39)",
|
backgroundColor: "rgba(255, 255, 255, 0.39)",
|
||||||
p: 5,
|
p: 5,
|
||||||
borderRadius:5
|
borderRadius: 5,
|
||||||
}}>
|
}}
|
||||||
<Typography variant="h1" sx={{ fontWeight: "bold", mb: 2, fontSize: { xs: "2rem", md: "3rem", lg: "3rem",whiteSpace: "pre-line" } }}>
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h1"
|
||||||
|
sx={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
mb: 2,
|
||||||
|
fontSize: {
|
||||||
|
xs: "2rem",
|
||||||
|
md: "3rem",
|
||||||
|
lg: "3rem",
|
||||||
|
whiteSpace: "pre-line",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
{title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ mb: 4 }}>
|
<Typography variant="body1" sx={{ mb: 4 }}>
|
||||||
@@ -89,7 +120,12 @@ const ServicePageTemplate = ({
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="large"
|
size="large"
|
||||||
sx={{ textTransform: "none", fontWeight: "bold", backgroundColor: "#0e467f", "&:hover": { backgroundColor: "#00bcd4" } }}
|
sx={{
|
||||||
|
textTransform: "none",
|
||||||
|
fontWeight: "bold",
|
||||||
|
backgroundColor: "#0e467f",
|
||||||
|
"&:hover": { backgroundColor: "#00bcd4" },
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{ctaText}
|
{ctaText}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -98,17 +134,41 @@ const ServicePageTemplate = ({
|
|||||||
|
|
||||||
{/* Section numero 1 */}
|
{/* Section numero 1 */}
|
||||||
<Box sx={{ padding: "40px 20px", textAlign: "center" }}>
|
<Box sx={{ padding: "40px 20px", textAlign: "center" }}>
|
||||||
<Typography variant="h2" sx={{ fontWeight: "bold", mb: 2, fontSize: { xs: "2rem", md: "2rem", lg: "2rem" }, whiteSpace: "pre-line" }}>
|
<Typography
|
||||||
|
variant="h2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
mb: 2,
|
||||||
|
fontSize: { xs: "2rem", md: "2rem", lg: "2rem" },
|
||||||
|
whiteSpace: "pre-line",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{interestTitle}
|
{interestTitle}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ maxWidth: "1000px", margin: "0 auto", mb: 4, whiteSpace: "pre-line" }}>
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
sx={{
|
||||||
|
maxWidth: "1000px",
|
||||||
|
margin: "0 auto",
|
||||||
|
mb: 4,
|
||||||
|
whiteSpace: "pre-line",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{description}
|
{description}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Section numero 2 */}
|
{/* Section numero 2 */}
|
||||||
<Box sx={{ backgroundColor: "#ffffff", padding: "40px 20px" }}>
|
<Box sx={{ backgroundColor: "#ffffff", padding: "40px 20px" }}>
|
||||||
<Typography variant="h2" sx={{ fontWeight: "bold", textAlign: "center", mb: 4, fontSize: { xs: "2rem", md: "3rem", lg: "2rem" } }}>
|
<Typography
|
||||||
|
variant="h2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
mb: 4,
|
||||||
|
fontSize: { xs: "2rem", md: "3rem", lg: "2rem" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
{desirTitle}
|
{desirTitle}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
@@ -127,12 +187,27 @@ const ServicePageTemplate = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Typography variant="h3" sx={{ fontWeight: "bold", mb: 2, fontSize: 26,whiteSpace: "pre-line" }}>
|
<Typography
|
||||||
|
variant="h3"
|
||||||
|
sx={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
mb: 2,
|
||||||
|
fontSize: 26,
|
||||||
|
whiteSpace: "pre-line",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{feature.title}
|
{feature.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" sx={{ color: "#555" }}>
|
<Typography
|
||||||
{feature.description}
|
variant="body2"
|
||||||
</Typography>
|
sx={{ color: "#555" }}
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html:
|
||||||
|
feature.description.length > 100
|
||||||
|
? `${feature.description.substring(0, 100)}...`
|
||||||
|
: feature.description,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -141,18 +216,51 @@ const ServicePageTemplate = ({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Modal */}
|
{/* Modal */}
|
||||||
<Modal open={openModal} onClose={handleCloseModal} closeAfterTransition BackdropComponent={Backdrop} BackdropProps={{ timeout: 500 }}>
|
<Modal
|
||||||
|
open={openModal}
|
||||||
|
onClose={handleCloseModal}
|
||||||
|
closeAfterTransition
|
||||||
|
BackdropComponent={Backdrop}
|
||||||
|
BackdropProps={{ timeout: 500 }}
|
||||||
|
>
|
||||||
<Fade in={openModal}>
|
<Fade in={openModal}>
|
||||||
<Box sx={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)", width: "90%", maxWidth: "600px", p: 4, textAlign: "center", background: "white", borderRadius: 2, boxShadow: 3 }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
width: "90%",
|
||||||
|
maxWidth: "600px",
|
||||||
|
p: 4,
|
||||||
|
textAlign: "center",
|
||||||
|
background: "white",
|
||||||
|
borderRadius: 2,
|
||||||
|
boxShadow: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{loadingImage && <CircularProgress sx={{ mb: 2 }} />}
|
{loadingImage && <CircularProgress sx={{ mb: 2 }} />}
|
||||||
<img src={modalContent.image} alt={modalContent.title} style={{ width: "100%", borderRadius: "8px", display: loadingImage ? "none" : "block" }} onLoad={() => setLoadingImage(false)} />
|
<img
|
||||||
|
src={modalContent.image}
|
||||||
|
alt={modalContent.title}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
borderRadius: "8px",
|
||||||
|
display: loadingImage ? "none" : "block",
|
||||||
|
}}
|
||||||
|
onLoad={() => setLoadingImage(false)}
|
||||||
|
/>
|
||||||
<Typography variant="h3" sx={{ fontWeight: "bold", mb: 2 }}>
|
<Typography variant="h3" sx={{ fontWeight: "bold", mb: 2 }}>
|
||||||
{modalContent.title}
|
{modalContent.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ mb: 4 }}>
|
<Typography variant="body1" sx={{ mb: 4 }} dangerouslySetInnerHTML={{ __html: modalContent.text }} >
|
||||||
{modalContent.text}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button onClick={handleCloseModal} variant="contained" color="secondary">
|
<Button
|
||||||
|
onClick={handleCloseModal}
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
Retour
|
Retour
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -167,11 +275,11 @@ const ServicePageTemplate = ({
|
|||||||
backgroundColor: "#f9f9f9",
|
backgroundColor: "#f9f9f9",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h2"
|
<Typography
|
||||||
|
variant="h2"
|
||||||
sx={{
|
sx={{
|
||||||
marginBottom: 4,
|
marginBottom: 4,
|
||||||
fontSize: { xs: '2rem', md: '3rem', lg: '3rem' }, // Responsive
|
fontSize: { xs: "2rem", md: "3rem", lg: "3rem" }, // Responsive
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Découvrez nos réalisations
|
Découvrez nos réalisations
|
||||||
@@ -208,10 +316,11 @@ const ServicePageTemplate = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Typography variant="h3"
|
<Typography
|
||||||
|
variant="h3"
|
||||||
sx={{
|
sx={{
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
fontSize: { xs: '1.2rem', md: '2rem', lg: '2.5rem' }, // Responsive
|
fontSize: { xs: "1.2rem", md: "2rem", lg: "2.5rem" }, // Responsive
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item.title}
|
{item.title}
|
||||||
@@ -224,7 +333,6 @@ const ServicePageTemplate = ({
|
|||||||
</Swiper>
|
</Swiper>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -236,11 +344,24 @@ ServicePageTemplate.propTypes = {
|
|||||||
interestTitle: PropTypes.string.isRequired,
|
interestTitle: PropTypes.string.isRequired,
|
||||||
description: PropTypes.string.isRequired,
|
description: PropTypes.string.isRequired,
|
||||||
desirTitle: PropTypes.string.isRequired,
|
desirTitle: PropTypes.string.isRequired,
|
||||||
features: PropTypes.arrayOf(PropTypes.shape({ title: PropTypes.string.isRequired, description: PropTypes.string.isRequired, modalText: PropTypes.string, modalImage: PropTypes.string })).isRequired,
|
features: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
description: PropTypes.string.isRequired,
|
||||||
|
modalText: PropTypes.string,
|
||||||
|
modalImage: PropTypes.string,
|
||||||
|
})
|
||||||
|
).isRequired,
|
||||||
image: PropTypes.string.isRequired,
|
image: PropTypes.string.isRequired,
|
||||||
ctaText: PropTypes.string.isRequired,
|
ctaText: PropTypes.string.isRequired,
|
||||||
ctaLink: PropTypes.string.isRequired,
|
ctaLink: PropTypes.string.isRequired,
|
||||||
carouselItems: PropTypes.arrayOf(PropTypes.shape({ title: PropTypes.string.isRequired, description: PropTypes.string.isRequired, image: PropTypes.string.isRequired })),
|
carouselItems: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
description: PropTypes.string.isRequired,
|
||||||
|
image: PropTypes.string.isRequired,
|
||||||
|
})
|
||||||
|
),
|
||||||
seo: PropTypes.object, // ✅ Ajout du SEO en option
|
seo: PropTypes.object, // ✅ Ajout du SEO en option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import ServiceUn from "./components/Pages/ServiceUn.jsx";
|
|||||||
import ServiceDeux from "./components/Pages/ServiceDeux.jsx";
|
import ServiceDeux from "./components/Pages/ServiceDeux.jsx";
|
||||||
import ServiceTrois from "./components/Pages/ServiceTrois.jsx";
|
import ServiceTrois from "./components/Pages/ServiceTrois.jsx";
|
||||||
import ServiceQuatre from "./components/Pages/ServiceQuatre.jsx";
|
import ServiceQuatre from "./components/Pages/ServiceQuatre.jsx";
|
||||||
|
import ServiceCinq from "./components/Pages/ServiceCinq.jsx";
|
||||||
|
|
||||||
// Import des composants globaux
|
// Import des composants globaux
|
||||||
import Header from "./components/Header";
|
import Header from "./components/Header";
|
||||||
@@ -60,6 +61,7 @@ function YourApp() {
|
|||||||
/>
|
/>
|
||||||
<Route path="/services/electricite" element={<ServiceTrois />} />
|
<Route path="/services/electricite" element={<ServiceTrois />} />
|
||||||
<Route path="/services/service-securite-incendie" element={<ServiceQuatre />} />
|
<Route path="/services/service-securite-incendie" element={<ServiceQuatre />} />
|
||||||
|
<Route path="/services/expertises-tce" element={<ServiceCinq />} />
|
||||||
<Route path="/admin/create-post" element={<CreatePost />} />
|
<Route path="/admin/create-post" element={<CreatePost />} />
|
||||||
<Route path="/post/:slug" element={<PostDetails />} />
|
<Route path="/post/:slug" element={<PostDetails />} />
|
||||||
<Route path="/admin/posts" element={<PostList />} />
|
<Route path="/admin/posts" element={<PostList />} />
|
||||||
|
|||||||
+4949
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user