summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2025-04-21 20:36:10 +0200
committerpolo <ordipolo@gmx.fr>2025-04-21 20:36:10 +0200
commiteb3e1eb8c8365d3b3d1d39f24314ba420255afc2 (patch)
tree5e3d747b0e4d5e747052e9afed76f3a0f0986379
parentca3949aca0c7c1af476c8eec93b4920d5aff21ec (diff)
downloadcms-eb3e1eb8c8365d3b3d1d39f24314ba420255afc2.zip
page menu et chemin, partie1
-rw-r--r--public/assets/arrow-down.svg11
-rw-r--r--public/assets/arrow-left-nb.svg36
-rw-r--r--public/assets/arrow-left.svg37
-rw-r--r--public/assets/arrow-right-nb.svg36
-rw-r--r--public/assets/arrow-right.svg37
-rw-r--r--public/assets/arrow-up.svg15
-rw-r--r--public/assets/book-open.svg9
-rw-r--r--public/assets/calendar.svg13
-rw-r--r--public/assets/delete-bin.svg11
-rw-r--r--public/assets/edit.svg11
-rw-r--r--public/assets/share.svg11
-rw-r--r--public/css/foot.css22
-rw-r--r--public/css/head.css2
-rw-r--r--public/css/menu.css72
-rw-r--r--public/js/main.js105
-rw-r--r--src/controller/Director.php2
-rw-r--r--src/controller/ajax.php44
-rw-r--r--src/controller/installation.php10
-rw-r--r--src/controller/password.php2
-rw-r--r--src/model/Position.php63
-rw-r--r--src/model/entities/Node.php33
-rw-r--r--src/model/entities/Page.php38
-rw-r--r--src/view/FooterBuilder.php2
-rw-r--r--src/view/HeaderBuilder.php2
-rw-r--r--src/view/MenuBuilder.php88
-rw-r--r--src/view/NavBuilder.php9
-rw-r--r--src/view/templates/header.php2
-rw-r--r--src/view/templates/menu.php15
28 files changed, 629 insertions, 109 deletions
diff --git a/public/assets/arrow-down.svg b/public/assets/arrow-down.svg
index bd7d579..6e5be60 100644
--- a/public/assets/arrow-down.svg
+++ b/public/assets/arrow-down.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="arrow-down.svg" 7 sodipodi:docname="arrow-down.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -22,18 +22,15 @@
22 inkscape:pagecheckerboard="0" 22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1" 23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="14.75" 24 inkscape:zoom="14.75"
25 inkscape:cx="12" 25 inkscape:cx="12.033898"
26 inkscape:cy="12.033898" 26 inkscape:cy="12.033898"
27 inkscape:window-width="1261" 27 inkscape:window-width="956"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="655" 29 inkscape:window-x="960"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M13.0001 16.1716L18.3641 10.8076L19.7783 12.2218L12.0001 20L4.22192 12.2218L5.63614 10.8076L11.0001 16.1716V4H13.0001V16.1716Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.256239" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.256239"
38 d="M 8.1361932,16.102295 4.2726833,12.238339 4.9491052,11.559369 5.6255269,10.8804 8.2707084,13.524946 c 1.4548498,1.4545 2.6679196,2.644546 2.6957116,2.644546 0.02779,0 0.05053,-2.730509 0.05053,-6.067797 V 4.0338983 H 12 12.983051 v 6.0677967 c 0,3.337288 0.02274,6.067797 0.05053,6.067797 0.02779,0 1.240862,-1.190046 2.695712,-2.644546 l 2.645181,-2.644546 0.676496,0.679044 0.676496,0.679044 -3.863881,3.863881 -3.863881,3.863882 z" 35 d="M 8.1361932,16.102295 4.2726833,12.238339 4.9491052,11.559369 5.6255269,10.8804 8.2707084,13.524946 c 1.4548498,1.4545 2.6679196,2.644546 2.6957116,2.644546 0.02779,0 0.05053,-2.730509 0.05053,-6.067797 V 4.0338983 H 12 12.983051 v 6.0677967 c 0,3.337288 0.02274,6.067797 0.05053,6.067797 0.02779,0 1.240862,-1.190046 2.695712,-2.644546 l 2.645181,-2.644546 0.676496,0.679044 0.676496,0.679044 -3.863881,3.863881 -3.863881,3.863882 z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/arrow-left-nb.svg b/public/assets/arrow-left-nb.svg
new file mode 100644
index 0000000..3f6a76f
--- /dev/null
+++ b/public/assets/arrow-left-nb.svg
@@ -0,0 +1,36 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 viewBox="0 0 24 24"
4 fill="currentColor"
5 version="1.1"
6 id="svg1"
7 sodipodi:docname="arrow-left-nb.svg"
8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg"
12 xmlns:svg="http://www.w3.org/2000/svg">
13 <defs
14 id="defs1" />
15 <sodipodi:namedview
16 id="namedview1"
17 pagecolor="#ffffff"
18 bordercolor="#000000"
19 borderopacity="0.25"
20 inkscape:showpageshadow="2"
21 inkscape:pageopacity="0.0"
22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="29.5"
25 inkscape:cx="12.525424"
26 inkscape:cy="11.745763"
27 inkscape:window-width="1916"
28 inkscape:window-height="1032"
29 inkscape:window-x="0"
30 inkscape:window-y="0"
31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" />
33 <path
34 d="m 7.82851,12.99999 5.364,5.364 -1.4142,1.4142 -7.7782,-7.7782 7.7782,-7.77818 1.4142,1.41422 -5.364,5.36396 h 12.1716 v 2 z"
35 id="path1" />
36</svg>
diff --git a/public/assets/arrow-left.svg b/public/assets/arrow-left.svg
new file mode 100644
index 0000000..191aaf3
--- /dev/null
+++ b/public/assets/arrow-left.svg
@@ -0,0 +1,37 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 viewBox="0 0 24 24"
4 fill="currentColor"
5 version="1.1"
6 id="svg1"
7 sodipodi:docname="arrow-left.svg"
8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg"
12 xmlns:svg="http://www.w3.org/2000/svg">
13 <defs
14 id="defs1" />
15 <sodipodi:namedview
16 id="namedview1"
17 pagecolor="#ffffff"
18 bordercolor="#000000"
19 borderopacity="0.25"
20 inkscape:showpageshadow="2"
21 inkscape:pageopacity="0.0"
22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="31.112698"
25 inkscape:cx="15.443855"
26 inkscape:cy="9.9155655"
27 inkscape:window-width="1916"
28 inkscape:window-height="1032"
29 inkscape:window-x="0"
30 inkscape:window-y="0"
31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" />
33 <path
34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.485914"
35 d="M 13.840048,12.935842 H 7.7022235 l 2.6973745,2.699672 2.697375,2.699671 -0.674256,0.674256 L 11.74846,19.683698 7.9248226,15.86006 4.1011848,12.036422 7.956427,8.1795725 l 3.855242,-3.856848 0.642652,0.642652 0.642652,0.642652 -2.697375,2.69967 -2.6973745,2.6996705 h 6.1378245 6.137824 v 0.964237 0.964236 z"
36 id="path2" />
37</svg>
diff --git a/public/assets/arrow-right-nb.svg b/public/assets/arrow-right-nb.svg
new file mode 100644
index 0000000..0b76c4e
--- /dev/null
+++ b/public/assets/arrow-right-nb.svg
@@ -0,0 +1,36 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 viewBox="0 0 24 24"
4 fill="currentColor"
5 version="1.1"
6 id="svg1"
7 sodipodi:docname="arrow-right-nb.svg"
8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg"
12 xmlns:svg="http://www.w3.org/2000/svg">
13 <defs
14 id="defs1" />
15 <sodipodi:namedview
16 id="namedview1"
17 pagecolor="#ffffff"
18 bordercolor="#000000"
19 borderopacity="0.25"
20 inkscape:showpageshadow="2"
21 inkscape:pageopacity="0.0"
22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="29.5"
25 inkscape:cx="12.525424"
26 inkscape:cy="11.745763"
27 inkscape:window-width="1916"
28 inkscape:window-height="1032"
29 inkscape:window-x="0"
30 inkscape:window-y="0"
31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" />
33 <path
34 d="m 16.17171,11.00001 -5.364,-5.364 1.4142,-1.4142 7.7782,7.7782 -7.7782,7.77818 -1.4142,-1.41422 5.364,-5.36396 H 4.00011 v -2 z"
35 id="path1" />
36</svg>
diff --git a/public/assets/arrow-right.svg b/public/assets/arrow-right.svg
new file mode 100644
index 0000000..976bfa4
--- /dev/null
+++ b/public/assets/arrow-right.svg
@@ -0,0 +1,37 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 viewBox="0 0 24 24"
4 fill="currentColor"
5 version="1.1"
6 id="svg1"
7 sodipodi:docname="arrow-right.svg"
8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg"
12 xmlns:svg="http://www.w3.org/2000/svg">
13 <defs
14 id="defs1" />
15 <sodipodi:namedview
16 id="namedview1"
17 pagecolor="#ffffff"
18 bordercolor="#000000"
19 borderopacity="0.25"
20 inkscape:showpageshadow="2"
21 inkscape:pageopacity="0.0"
22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="31.112698"
25 inkscape:cx="15.443855"
26 inkscape:cy="9.9155655"
27 inkscape:window-width="1916"
28 inkscape:window-height="1032"
29 inkscape:window-x="0"
30 inkscape:window-y="0"
31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" />
33 <path
34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.485914"
35 d="m 10.138408,11.070544 h 6.137825 l -2.697375,-2.6996714 -2.697375,-2.6996709 0.674256,-0.6742566 0.674257,-0.6742565 3.823638,3.8236378 3.823638,3.8236376 -3.855242,3.85685 -3.855243,3.856848 -0.642652,-0.642652 -0.642652,-0.642652 2.697375,-2.69967 2.697375,-2.699671 H 10.138408 4.0005845 V 12.03478 11.070544 Z"
36 id="path2" />
37</svg>
diff --git a/public/assets/arrow-up.svg b/public/assets/arrow-up.svg
index c88794d..bbacb0d 100644
--- a/public/assets/arrow-up.svg
+++ b/public/assets/arrow-up.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="arrow-up.svg" 7 sodipodi:docname="arrow-up.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -21,19 +21,16 @@
21 inkscape:pageopacity="0.0" 21 inkscape:pageopacity="0.0"
22 inkscape:pagecheckerboard="0" 22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1" 23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="7.7781746" 24 inkscape:zoom="31.112698"
25 inkscape:cx="19.734707" 25 inkscape:cx="15.443855"
26 inkscape:cy="19.220448" 26 inkscape:cy="9.9155655"
27 inkscape:window-width="956" 27 inkscape:window-width="1916"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="960" 29 inkscape:window-x="0"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M13.0001 7.82843V20H11.0001V7.82843L5.63614 13.1924L4.22192 11.7782L12.0001 4L19.7783 11.7782L18.3641 13.1924L13.0001 7.82843Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.485914" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.485914"
38 d="M 11.056579,13.854013 V 7.7161883 L 8.3569078,10.413563 5.6572369,13.110938 4.9829803,12.436682 4.3087238,11.762425 8.1323616,7.9387874 11.955999,4.1151496 l 3.85685,3.8552422 3.856848,3.8552422 -0.642652,0.642652 -0.642652,0.642652 -2.69967,-2.697375 -2.699671,-2.6973747 v 6.1378247 6.137824 h -0.964237 -0.964236 z" 35 d="M 11.056579,13.854013 V 7.7161883 L 8.3569078,10.413563 5.6572369,13.110938 4.9829803,12.436682 4.3087238,11.762425 8.1323616,7.9387874 11.955999,4.1151496 l 3.85685,3.8552422 3.856848,3.8552422 -0.642652,0.642652 -0.642652,0.642652 -2.69967,-2.697375 -2.699671,-2.6973747 v 6.1378247 6.137824 h -0.964237 -0.964236 z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/book-open.svg b/public/assets/book-open.svg
index 383bc6d..1d24a52 100644
--- a/public/assets/book-open.svg
+++ b/public/assets/book-open.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="book-open.svg" 7 sodipodi:docname="book-open.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -24,16 +24,13 @@
24 inkscape:zoom="16.333333" 24 inkscape:zoom="16.333333"
25 inkscape:cx="13.714286" 25 inkscape:cx="13.714286"
26 inkscape:cy="10.010204" 26 inkscape:cy="10.010204"
27 inkscape:window-width="1367" 27 inkscape:window-width="1916"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="549" 29 inkscape:window-x="0"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M13 21V23H11V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H9C10.1947 3 11.2671 3.52375 12 4.35418C12.7329 3.52375 13.8053 3 15 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H13ZM20 19V5H15C13.8954 5 13 5.89543 13 7V19H20ZM11 19V7C11 5.89543 10.1046 5 9 5H4V19H11Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.462799" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.462799"
38 d="m 11.020408,21.985643 v -0.97354 L 6.8668354,20.975439 2.7132626,20.938776 2.3974476,20.641921 2.0816327,20.345066 V 12 3.6549341 l 0.3162118,-0.2968548 0.3162119,-0.2968548 3.5103187,0.00234 c 3.2760872,0.00218 3.5522704,0.01942 4.1390279,0.2583701 0.34579,0.1408189 0.852538,0.4359086 1.126107,0.655755 l 0.497399,0.3997205 0.605683,-0.4446121 c 1.1434,-0.8393329 1.270609,-0.8605967 5.183033,-0.8663802 l 3.510319,-0.00519 0.316211,0.2968548 0.316212,0.2968548 V 12 20.345066 l -0.315815,0.296855 -0.315814,0.296855 -4.153574,0.03666 -4.153572,0.03666 v 0.97354 0.973541 H 12 11.020408 Z m 0,-9.294065 V 6.3423387 L 10.744898,5.9375303 C 10.12681,5.0293713 10.107047,5.0245329 6.8484856,4.9836104 L 3.9183674,4.9468125 v 7.0470025 7.047001 h 3.5510204 3.5510202 z m 9.061225,-0.697763 V 4.9468125 l -2.930119,0.036798 c -3.258561,0.040922 -3.278324,0.045761 -3.896412,0.9539199 l -0.27551,0.4048084 v 6.3492392 6.349238 h 3.55102 3.551021 z" 35 d="m 11.020408,21.985643 v -0.97354 L 6.8668354,20.975439 2.7132626,20.938776 2.3974476,20.641921 2.0816327,20.345066 V 12 3.6549341 l 0.3162118,-0.2968548 0.3162119,-0.2968548 3.5103187,0.00234 c 3.2760872,0.00218 3.5522704,0.01942 4.1390279,0.2583701 0.34579,0.1408189 0.852538,0.4359086 1.126107,0.655755 l 0.497399,0.3997205 0.605683,-0.4446121 c 1.1434,-0.8393329 1.270609,-0.8605967 5.183033,-0.8663802 l 3.510319,-0.00519 0.316211,0.2968548 0.316212,0.2968548 V 12 20.345066 l -0.315815,0.296855 -0.315814,0.296855 -4.153574,0.03666 -4.153572,0.03666 v 0.97354 0.973541 H 12 11.020408 Z m 0,-9.294065 V 6.3423387 L 10.744898,5.9375303 C 10.12681,5.0293713 10.107047,5.0245329 6.8484856,4.9836104 L 3.9183674,4.9468125 v 7.0470025 7.047001 h 3.5510204 3.5510202 z m 9.061225,-0.697763 V 4.9468125 l -2.930119,0.036798 c -3.258561,0.040922 -3.278324,0.045761 -3.896412,0.9539199 l -0.27551,0.4048084 v 6.3492392 6.349238 h 3.55102 3.551021 z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/calendar.svg b/public/assets/calendar.svg
index d8a0862..2a1100d 100644
--- a/public/assets/calendar.svg
+++ b/public/assets/calendar.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="calendar.svg" 7 sodipodi:docname="calendar.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -22,18 +22,15 @@
22 inkscape:pagecheckerboard="0" 22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1" 23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="16.333333" 24 inkscape:zoom="16.333333"
25 inkscape:cx="10.867347" 25 inkscape:cx="10.836735"
26 inkscape:cy="7.0714286" 26 inkscape:cy="7.0714287"
27 inkscape:window-width="1378" 27 inkscape:window-width="1916"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="538" 29 inkscape:window-x="0"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M9 1V3H15V1H17V3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H7V1H9ZM20 11H4V19H20V11ZM7 5H4V9H20V5H17V7H15V5H9V7H7V5Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke-width:0.2314;fill-opacity:1" 34 style="fill:#dd3333;stroke-width:0.2314;fill-opacity:1"
38 d="M 2.6632967,20.900914 C 2.5791303,20.867183 2.4456452,20.779249 2.3666632,20.705506 2.0328996,20.393883 2.0510204,20.894721 2.0510204,11.981482 V 3.7221898 L 2.1887755,3.5197856 C 2.2645408,3.4084632 2.4042737,3.2597461 2.4992931,3.1893029 2.6658093,3.0658553 2.7504798,3.0605903 4.8411299,3.0436855 L 7.0102041,3.0261465 V 2.0181753 1.0102041 h 0.9795918 0.9795919 v 1.0102041 1.010204 H 12 15.030612 V 2.0204082 1.0102041 h 0.979592 0.979592 v 1.0079712 1.0079712 l 2.169074,0.017539 c 2.09065,0.016905 2.175321,0.02217 2.341837,0.1456174 0.09502,0.070443 0.234752,0.2191603 0.310518,0.3304827 L 21.94898,3.7221898 V 12 20.27781 l -0.137755,0.202405 c -0.07577,0.111322 -0.215538,0.260039 -0.310605,0.330482 l -0.17285,0.128079 -9.255722,0.01173 c -6.0661846,0.0077 -9.3084558,-0.0094 -9.4087513,-0.0496 z M 20.05102,15 V 10.989796 H 12 3.9489796 V 15 19.010204 H 12 20.05102 Z m 0,-7.9897959 V 4.9897959 H 18.520408 16.989796 V 5.9693878 6.9489796 H 16.010204 15.030612 V 5.9693878 4.9897959 H 12 8.9693878 V 5.9693878 6.9489796 H 7.9897959 7.0102041 V 5.9693878 4.9897959 H 5.4795918 3.9489796 V 7.0102041 9.0306123 H 12 20.05102 Z" 35 d="M 2.6632967,20.900914 C 2.5791303,20.867183 2.4456452,20.779249 2.3666632,20.705506 2.0328996,20.393883 2.0510204,20.894721 2.0510204,11.981482 V 3.7221898 L 2.1887755,3.5197856 C 2.2645408,3.4084632 2.4042737,3.2597461 2.4992931,3.1893029 2.6658093,3.0658553 2.7504798,3.0605903 4.8411299,3.0436855 L 7.0102041,3.0261465 V 2.0181753 1.0102041 h 0.9795918 0.9795919 v 1.0102041 1.010204 H 12 15.030612 V 2.0204082 1.0102041 h 0.979592 0.979592 v 1.0079712 1.0079712 l 2.169074,0.017539 c 2.09065,0.016905 2.175321,0.02217 2.341837,0.1456174 0.09502,0.070443 0.234752,0.2191603 0.310518,0.3304827 L 21.94898,3.7221898 V 12 20.27781 l -0.137755,0.202405 c -0.07577,0.111322 -0.215538,0.260039 -0.310605,0.330482 l -0.17285,0.128079 -9.255722,0.01173 c -6.0661846,0.0077 -9.3084558,-0.0094 -9.4087513,-0.0496 z M 20.05102,15 V 10.989796 H 12 3.9489796 V 15 19.010204 H 12 20.05102 Z m 0,-7.9897959 V 4.9897959 H 18.520408 16.989796 V 5.9693878 6.9489796 H 16.010204 15.030612 V 5.9693878 4.9897959 H 12 8.9693878 V 5.9693878 6.9489796 H 7.9897959 7.0102041 V 5.9693878 4.9897959 H 5.4795918 3.9489796 V 7.0102041 9.0306123 H 12 20.05102 Z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/delete-bin.svg b/public/assets/delete-bin.svg
index d534c53..69f9f03 100644
--- a/public/assets/delete-bin.svg
+++ b/public/assets/delete-bin.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="delete-bin.svg" 7 sodipodi:docname="delete-bin.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -22,18 +22,15 @@
22 inkscape:pagecheckerboard="0" 22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1" 23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="5.7747054" 24 inkscape:zoom="5.7747054"
25 inkscape:cx="8.0523589" 25 inkscape:cx="8.0523588"
26 inkscape:cy="13.940105" 26 inkscape:cy="13.940105"
27 inkscape:window-width="956" 27 inkscape:window-width="636"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="960" 29 inkscape:window-x="640"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM18 8H6V20H18V8ZM9 11H11V17H9V11ZM13 11H15V17H13V11ZM9 4V6H15V4H9Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.654497" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.654497"
38 d="M 4.428179,21.633757 C 4.1901151,21.395692 4.1560562,20.517904 4.1560562,14.620412 V 7.8791899 H 3.1170421 2.0780281 V 7.0133448 6.1474998 H 4.5889787 7.0999293 V 4.4910099 c 0,-0.9110696 0.080668,-1.8072192 0.1792618,-1.9914437 0.1701493,-0.317927 0.4073212,-0.3349536 4.6657439,-0.3349536 5.369132,0 5.025628,-0.1624223 5.025628,2.3763127 v 1.6065745 h 2.51095 2.510951 v 0.865845 0.8658451 H 20.95345 19.914436 v 6.7267521 c 0,6.296846 -0.02024,6.745069 -0.316681,7.013345 -0.28412,0.257124 -1.066299,0.286592 -7.607067,0.286592 -6.396732,0 -7.3237431,-0.03336 -7.562509,-0.272122 z M 18.009577,13.940105 V 7.8791899 H 11.948662 5.8877463 v 6.0609151 6.060915 h 6.0609157 6.060915 z M 15.065704,5.0219012 V 3.8963027 H 11.948662 8.8316194 v 1.0101525 c 0,0.555584 0.051951,1.0621033 0.1154461,1.1255985 0.063495,0.063495 1.4661645,0.1154461 3.1170425,0.1154461 h 3.001596 z" 35 d="M 4.428179,21.633757 C 4.1901151,21.395692 4.1560562,20.517904 4.1560562,14.620412 V 7.8791899 H 3.1170421 2.0780281 V 7.0133448 6.1474998 H 4.5889787 7.0999293 V 4.4910099 c 0,-0.9110696 0.080668,-1.8072192 0.1792618,-1.9914437 0.1701493,-0.317927 0.4073212,-0.3349536 4.6657439,-0.3349536 5.369132,0 5.025628,-0.1624223 5.025628,2.3763127 v 1.6065745 h 2.51095 2.510951 v 0.865845 0.8658451 H 20.95345 19.914436 v 6.7267521 c 0,6.296846 -0.02024,6.745069 -0.316681,7.013345 -0.28412,0.257124 -1.066299,0.286592 -7.607067,0.286592 -6.396732,0 -7.3237431,-0.03336 -7.562509,-0.272122 z M 18.009577,13.940105 V 7.8791899 H 11.948662 5.8877463 v 6.0609151 6.060915 h 6.0609157 6.060915 z M 15.065704,5.0219012 V 3.8963027 H 11.948662 8.8316194 v 1.0101525 c 0,0.555584 0.051951,1.0621033 0.1154461,1.1255985 0.063495,0.063495 1.4661645,0.1154461 3.1170425,0.1154461 h 3.001596 z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/edit.svg b/public/assets/edit.svg
index 2c1fd10..17b2dec 100644
--- a/public/assets/edit.svg
+++ b/public/assets/edit.svg
@@ -5,7 +5,7 @@
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="edit.svg" 7 sodipodi:docname="edit.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -22,18 +22,15 @@
22 inkscape:pagecheckerboard="0" 22 inkscape:pagecheckerboard="0"
23 inkscape:deskcolor="#d1d1d1" 23 inkscape:deskcolor="#d1d1d1"
24 inkscape:zoom="8.1666667" 24 inkscape:zoom="8.1666667"
25 inkscape:cx="18.979592" 25 inkscape:cx="19.040816"
26 inkscape:cy="21.734694" 26 inkscape:cy="21.734694"
27 inkscape:window-width="1347" 27 inkscape:window-width="636"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="569" 29 inkscape:window-x="640"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M6.41421 15.89L16.5563 5.74785L15.1421 4.33363L5 14.4758V15.89H6.41421ZM7.24264 17.89H3V13.6473L14.435 2.21231C14.8256 1.82179 15.4587 1.82179 15.8492 2.21231L18.6777 5.04074C19.0682 5.43126 19.0682 6.06443 18.6777 6.45495L7.24264 17.89ZM3 19.89H21V21.89H3V19.89Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.462799" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.462799"
38 d="M 3.0612245,20.877551 V 19.897959 H 12 20.938776 v 0.979592 0.979592 H 12 3.0612245 Z" 35 d="M 3.0612245,20.877551 V 19.897959 H 12 20.938776 v 0.979592 0.979592 H 12 3.0612245 Z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/assets/share.svg b/public/assets/share.svg
index e053051..eb47002 100644
--- a/public/assets/share.svg
+++ b/public/assets/share.svg
@@ -4,8 +4,8 @@
4 fill="currentColor" 4 fill="currentColor"
5 version="1.1" 5 version="1.1"
6 id="svg1" 6 id="svg1"
7 sodipodi:docname="share-forward.svg" 7 sodipodi:docname="share.svg"
8 inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 8 inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns="http://www.w3.org/2000/svg" 11 xmlns="http://www.w3.org/2000/svg"
@@ -24,16 +24,13 @@
24 inkscape:zoom="5.3333333" 24 inkscape:zoom="5.3333333"
25 inkscape:cx="18.46875" 25 inkscape:cx="18.46875"
26 inkscape:cy="16.03125" 26 inkscape:cy="16.03125"
27 inkscape:window-width="956" 27 inkscape:window-width="636"
28 inkscape:window-height="1032" 28 inkscape:window-height="1032"
29 inkscape:window-x="960" 29 inkscape:window-x="640"
30 inkscape:window-y="0" 30 inkscape:window-y="0"
31 inkscape:window-maximized="1" 31 inkscape:window-maximized="1"
32 inkscape:current-layer="svg1" /> 32 inkscape:current-layer="svg1" />
33 <path 33 <path
34 d="M13 14H11C7.54202 14 4.53953 15.9502 3.03239 18.8107C3.01093 18.5433 3 18.2729 3 18C3 12.4772 7.47715 8 13 8V2.5L23.5 11L13 19.5V14ZM11 12H15V15.3078L20.3214 11L15 6.69224V10H13C10.5795 10 8.41011 11.0749 6.94312 12.7735C8.20873 12.2714 9.58041 12 11 12Z"
35 id="path1" />
36 <path
37 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.708661" 34 style="fill:#dd3333;stroke:#dd3333;stroke-width:0.708661"
38 d="m 13.125,16.62281 v -2.65406 l -1.734375,0.0046 c -3.1289994,0.0083 -4.7715187,0.662267 -6.84375,2.72496 L 3.1875,18.051411 3.1920836,17.275706 C 3.2079642,14.588168 5.033385,11.457683 7.5641723,9.7778419 8.8054939,8.9538996 11.118995,8.15625 12.267434,8.15625 H 13.125 V 5.5156251 c 0,-1.4523438 0.07229,-2.6125001 0.160633,-2.5781251 0.344223,0.1339326 9.936632,7.944961 9.904618,8.065257 -0.0187,0.07027 -2.143376,1.831888 -4.721501,3.914713 -2.578125,2.082826 -4.835156,3.915756 -5.015625,4.073178 C 13.142599,19.261519 13.125,19.134524 13.125,16.62281 Z m 7.253039,-5.611275 c 0.01886,-0.07509 -1.162391,-1.0943592 -2.625,-2.2650333 L 15.09375,6.6180036 15.039575,8.2308767 14.9854,9.84375 13.914575,9.844836 c -1.658785,0.00168 -3.170519,0.311395 -4.4246483,0.906488 -1.150183,0.545771 -2.7354857,1.775452 -2.5436777,1.97307 0.056375,0.05808 0.520437,-0.02888 1.03125,-0.193243 0.6245522,-0.200964 1.9267104,-0.328748 3.975626,-0.390138 L 15,12.049721 v 1.702541 1.70254 l 2.671875,-2.153366 c 1.469531,-1.184352 2.687305,-2.214808 2.706164,-2.289901 z" 35 d="m 13.125,16.62281 v -2.65406 l -1.734375,0.0046 c -3.1289994,0.0083 -4.7715187,0.662267 -6.84375,2.72496 L 3.1875,18.051411 3.1920836,17.275706 C 3.2079642,14.588168 5.033385,11.457683 7.5641723,9.7778419 8.8054939,8.9538996 11.118995,8.15625 12.267434,8.15625 H 13.125 V 5.5156251 c 0,-1.4523438 0.07229,-2.6125001 0.160633,-2.5781251 0.344223,0.1339326 9.936632,7.944961 9.904618,8.065257 -0.0187,0.07027 -2.143376,1.831888 -4.721501,3.914713 -2.578125,2.082826 -4.835156,3.915756 -5.015625,4.073178 C 13.142599,19.261519 13.125,19.134524 13.125,16.62281 Z m 7.253039,-5.611275 c 0.01886,-0.07509 -1.162391,-1.0943592 -2.625,-2.2650333 L 15.09375,6.6180036 15.039575,8.2308767 14.9854,9.84375 13.914575,9.844836 c -1.658785,0.00168 -3.170519,0.311395 -4.4246483,0.906488 -1.150183,0.545771 -2.7354857,1.775452 -2.5436777,1.97307 0.056375,0.05808 0.520437,-0.02888 1.03125,-0.193243 0.6245522,-0.200964 1.9267104,-0.328748 3.975626,-0.390138 L 15,12.049721 v 1.702541 1.70254 l 2.671875,-2.153366 c 1.469531,-1.184352 2.687305,-2.214808 2.706164,-2.289901 z"
39 id="path2" /> 36 id="path2" />
diff --git a/public/css/foot.css b/public/css/foot.css
index 0e454ac..91f67ab 100644
--- a/public/css/foot.css
+++ b/public/css/foot.css
@@ -124,3 +124,25 @@ footer > div
124 background-color: #ffff00; 124 background-color: #ffff00;
125 border-radius: 4px; 125 border-radius: 4px;
126} 126}
127
128.toast {
129 visibility: hidden;
130 /*max-width: 50%;*/
131 margin: auto;
132 background-color: #333;
133 color: #fff;
134 text-align: center;
135 border-radius: 5px;
136 padding: 16px;
137 position: fixed;
138 z-index: 1;
139 left: 50%;
140 bottom: 30px;
141 transform: translateX(-50%);
142 /*opacity: 0;*/
143 transition: opacity 0.5s, visibility 0.5s;
144}
145.toast.show {
146 visibility: visible;
147 opacity: 1;
148} \ No newline at end of file
diff --git a/public/css/head.css b/public/css/head.css
index a718a45..4872275 100644
--- a/public/css/head.css
+++ b/public/css/head.css
@@ -6,7 +6,7 @@ header
6 background-image: url('../assets/fond-piscine.jpg'); 6 background-image: url('../assets/fond-piscine.jpg');
7 background-size: cover; /* largeur du bloc_page */ 7 background-size: cover; /* largeur du bloc_page */
8} 8}
9.empty_nav_zone 9#nav_zone
10{ 10{
11 /*margin: auto;*/ 11 /*margin: auto;*/
12 /*max-width: 1200px;*/ 12 /*max-width: 1200px;*/
diff --git a/public/css/menu.css b/public/css/menu.css
new file mode 100644
index 0000000..cce1d43
--- /dev/null
+++ b/public/css/menu.css
@@ -0,0 +1,72 @@
1/* page "Menu et chemins" uniquement */
2
3.menu
4{
5 padding: 0 20px;
6}
7.menu img
8{
9 width: 20px;
10 vertical-align: middle;
11}
12
13/* explications pour l'utiisateur */
14.menu aside
15{
16 display: flex;
17 flex-wrap: wrap;
18 background-color: white;
19 padding: 10px;
20}
21.menu aside p
22{
23 margin: 5px;
24 font-size: smaller;
25}
26.menu aside input
27{
28 pointer-events: none; /* case non clicable, sauf action au clavier... */
29}
30
31.menu button
32{
33 margin: 5px;
34}
35input
36{
37 vertical-align: middle;
38}
39.menu_entry_checkbox
40{
41 margin-left: 2px;
42}
43.move_entry_icon
44{
45 width: 20px;
46 vertical-align: middle;
47 border: 2px #e3f3ff solid;
48}
49.move_entry_icon:hover
50{
51 background-color: #ffff00;
52 border-radius: 4px;
53 border: lightgrey 2px outset;
54 cursor: pointer;
55}
56
57.menu .new_entry_buttons
58{
59 background-color: white;
60 padding: 10px;
61}
62.menu .new_entry_buttons p
63{
64 margin: 5px;
65}
66
67@media screen and (min-width: 80rem) {
68 i
69 {
70 /*display: none;*/
71 }
72} \ No newline at end of file
diff --git a/public/js/main.js b/public/js/main.js
index cb76ea8..fadcfa9 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -29,10 +29,17 @@ function copyInClipBoard(link){
29 alert('Cette adresse a été copiée dans le presse-papier:\n\n' + link); 29 alert('Cette adresse a été copiée dans le presse-papier:\n\n' + link);
30} 30}
31 31
32function toastNotify(message) {
33 var toast = document.getElementById('toast');
34 toast.textContent = message;
35 toast.className = 'toast show';
36 setTimeout(function(){ toast.className = toast.className.replace('show', ''); }, 3000);
37}
38
32// complète les fonctions dans tinymce.js 39// complète les fonctions dans tinymce.js
33function switchPositions(article_id, direction) 40function switchPositions(article_id, direction)
34{ 41{
35 const current_article = findParent(document.getElementById(article_id), 'article'); 42 const current_article = findParent(document.getElementById(article_id), 'article'); // l'id n'est pas sur la bonne balise
36 var other_article; 43 var other_article;
37 44
38 if(direction == 'down'){ 45 if(direction == 'down'){
@@ -195,4 +202,100 @@ function findParent(element, tag_name){
195 element = element.parentElement; 202 element = element.parentElement;
196 } 203 }
197 return null; 204 return null;
205}
206
207/* page Menu et chemins */
208function moveOneLevelUp(){}
209function moveOneLevelDown(){}
210
211function switchMenuPositions(page_id, direction)
212{
213 const nav_zone = document.getElementById("nav_zone"); // parent de <nav>
214 const clicked_menu_entry = document.getElementById(page_id); // div parente du bouton
215 var other_entry = null;
216
217 // pas bon
218 if(direction == 'down'){
219 other_entry = clicked_menu_entry.nextElementSibling;
220 }
221 else if(direction == 'up'){
222 other_entry = clicked_menu_entry.previousElementSibling;
223 }
224
225 if(other_entry == null){
226 console.log('Inversion impossible');
227 return;
228 }
229
230 fetch('index.php?menu_edit=switch_positions', {
231 method: 'POST',
232 headers: {
233 'Content-Type': 'application/json'
234 },
235 body: JSON.stringify({ id1: clicked_menu_entry.id, id2: other_entry.id })
236 })
237 .then(response => response.json())
238 .then(data => {
239 if(data.success)
240 {
241 if(direction == 'down'){
242 clicked_menu_entry.parentElement.insertBefore(other_entry, clicked_menu_entry);
243 console.log('Inversion réussie');
244 }
245 else if(direction == 'up'){
246 other_entry.parentElement.insertBefore(clicked_menu_entry, other_entry);
247 console.log('Inversion réussie');
248 }
249 else{
250 console.error('Échec de l\'inversion');
251 }
252
253 // remplacement du menu
254 nav_zone.innerHTML = '';
255 nav_zone.insertAdjacentHTML('afterbegin', data.nav);
256 }
257 else {
258
259 console.error('Échec de l\'inversion');
260 }
261 })
262 .catch(error => {
263 console.error('Erreur:', error);
264 });
265}
266
267function checkMenuEntry(page_id){
268 const clicked_menu_entry = document.getElementById(page_id); // div parente du bouton
269 const checkbox = clicked_menu_entry.querySelector("input");
270
271 let color;
272 if(checkbox.checked){
273 color = "#ff1d04";
274 checked = true;
275 }
276 else{
277 color = "grey";
278 checked = false;
279 }
280
281 // contrôle check impossible si le parent le plus ancien est unchecked
282 //
283
284 // sur l'élément concerné
285 clicked_menu_entry.querySelector("button").style.color = color;
286
287 // même chose sur les enfants
288 /*try{
289 const level_markup = clicked_menu_entry.querySelector('.level');
290 //const other_buttons = .querySelectorAll("button");
291 level_markup.querySelectorAll("input").forEach(input => {
292 input.checked = checked;
293 });
294 level_markup.querySelectorAll("button").forEach(button => {
295 button.style.color = color;
296 });
297 }
298 catch(error){
299 console.log("pas d'enfant");
300 }*/
198} \ No newline at end of file 301} \ No newline at end of file
diff --git a/src/controller/Director.php b/src/controller/Director.php
index b7be9b8..a2528ed 100644
--- a/src/controller/Director.php
+++ b/src/controller/Director.php
@@ -11,7 +11,7 @@ class Director
11{ 11{
12 private EntityManager $entityManager; 12 private EntityManager $entityManager;
13 static public Menu $menu_data; // pour NavBuilder 13 static public Menu $menu_data; // pour NavBuilder
14 static public Path $page_path; // pour BreadcrumbBuilder 14 static public ?Path $page_path = null; // pour $current dans NavBuilder et pour BreadcrumbBuilder
15 private Page $page; 15 private Page $page;
16 private Node $node; 16 private Node $node;
17 private Node $article; 17 private Node $article;
diff --git a/src/controller/ajax.php b/src/controller/ajax.php
index a4b61e4..c774bf3 100644
--- a/src/controller/ajax.php
+++ b/src/controller/ajax.php
@@ -6,7 +6,7 @@ declare(strict_types=1);
6use App\Entity\Article; 6use App\Entity\Article;
7use App\Entity\Node; 7use App\Entity\Node;
8 8
9// détection des requêtes de tinymce 9// détection des requêtes de tinymce ou touchant aux articles
10if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action'])) 10if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
11{ 11{
12 // récupération des données 12 // récupération des données
@@ -204,6 +204,48 @@ if(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_
204 die; 204 die;
205} 205}
206 206
207if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['menu_edit']))
208{
209 // récupération des données
210 $data = file_get_contents('php://input');
211 $json = json_decode($data, true);
212
213 if($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2']))
214 {
215 //$menu = new Menu($entityManager);
216 Director::$menu_data = new Menu($entityManager);
217
218 $id1 = $json['id1'];
219 $id2 = $json['id2'];
220
221 // vérifier qu'ils ont le même parent
222 $page1 = Director::$menu_data->findPageById((int)$id1);
223 $page2 = Director::$menu_data->findPageById((int)$id2);
224
225 // double le contrôle fait en JS
226 if($page1->getParent() === $page2->getParent()) // comparaison stricte d'objet (même instance du parent?)
227 {
228 // inversion
229 $tmp = $page1->getPosition();
230 $page1->setPosition($page2->getPosition());
231 $page2->setPosition($tmp);
232 Director::$menu_data->sortChildren(true); // modifie tableau children
233 $entityManager->flush();
234
235 // menu utilisant les nouvelles données
236 //Director::$page_path = new Path();
237 $nav_builder = new NavBuilder(); // builder appelé sans envoi du noeud correspondant
238
239 echo json_encode(['success' => true, 'path1' => '', 'path2' => '', 'nav' => $nav_builder->render()]);
240 }
241 else{
242 echo json_encode(['success' => false]);
243 }
244
245 die;
246 }
247}
248
207// détection des requêtes de type XHR, pas d'utilité pour l'instant 249// détection des requêtes de type XHR, pas d'utilité pour l'instant
208/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){ 250/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
209 echo "requête XHR reçue par le serveur"; 251 echo "requête XHR reçue par le serveur";
diff --git a/src/controller/installation.php b/src/controller/installation.php
index c2b38fd..ff168eb 100644
--- a/src/controller/installation.php
+++ b/src/controller/installation.php
@@ -80,9 +80,9 @@ function makeStartPage(EntityManager $entityManager){
80 $accueil = new Page('Accueil', 'accueil', true, true, 1, NULL); 80 $accueil = new Page('Accueil', 'accueil', true, true, 1, NULL);
81 $connection = new Page('Connexion', 'connexion', true, false, NULL, NULL); 81 $connection = new Page('Connexion', 'connexion', true, false, NULL, NULL);
82 $article = new Page('Article', 'article', true, false, NULL, NULL); 82 $article = new Page('Article', 'article', true, false, NULL, NULL);
83 $menu_paths = new Page("Menu et chemins", 'menu_chemins', true, false, NULL, NULL);
83 $edit_page = new Page("Modification d'une page", 'modif_page', true, false, NULL, NULL); 84 $edit_page = new Page("Modification d'une page", 'modif_page', true, false, NULL, NULL);
84 $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, NULL, NULL); 85 $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, NULL, NULL);
85 $edit_paths = new Page("Menu et chemins", 'menu_chemins', true, false, NULL, NULL);
86 86
87 /* -- table node -- */ 87 /* -- table node -- */
88 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article 88 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article
@@ -95,6 +95,8 @@ function makeStartPage(EntityManager $entityManager){
95 $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav', 'main'], 'js_array' => ['main']], 1, NULL, $connection, NULL); 95 $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav', 'main'], 'js_array' => ['main']], 1, NULL, $connection, NULL);
96 $login = new Node('login', NULL, [], 1, $main, $connection, NULL); 96 $login = new Node('login', NULL, [], 1, $main, $connection, NULL);
97 $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL); 97 $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL);
98 $head_edit_menu = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'menu'], 'js_array' => ['main']], 1, NULL, $menu_paths, NULL);
99 $edit_menu = new Node('menu', NULL, [], 1, $main, $menu_paths, NULL);
98 100
99 /* -- table image -- */ 101 /* -- table image -- */
100 // paramètres: file_name, file_path, file_path_mini, mime_type, alt 102 // paramètres: file_name, file_path, file_path_mini, mime_type, alt
@@ -111,13 +113,14 @@ function makeStartPage(EntityManager $entityManager){
111 $footer_data = new NodeData(["adresse" => "17, rue Raymonde Folgoas Guillou, 29120 Pont-l’Abbé", "contact_nom" => "Les Nageurs Bigoudens", "e_mail" => "nb.secretariat@orange.fr", "logo_footer" => "assets/logo-nb-et-ffn.png"], $footer); 113 $footer_data = new NodeData(["adresse" => "17, rue Raymonde Folgoas Guillou, 29120 Pont-l’Abbé", "contact_nom" => "Les Nageurs Bigoudens", "e_mail" => "nb.secretariat@orange.fr", "logo_footer" => "assets/logo-nb-et-ffn.png"], $footer);
112 $head_login_data = new NodeData(["description" => "Connexion", "title" => "Connexion"], $head_login, new ArrayCollection([$favicon])); 114 $head_login_data = new NodeData(["description" => "Connexion", "title" => "Connexion"], $head_login, new ArrayCollection([$favicon]));
113 $head_article_data = new NodeData(["description" => "", "title" => ""], $head_article, new ArrayCollection([$favicon])); 115 $head_article_data = new NodeData(["description" => "", "title" => ""], $head_article, new ArrayCollection([$favicon]));
116 $head_edit_menu_data = new NodeData(["description" => "Menu et chemins", "title" => "Menu et chemins"], $head_edit_menu, new ArrayCollection([$favicon]));
114 117
115 $entityManager->persist($accueil); 118 $entityManager->persist($accueil);
116 $entityManager->persist($connection); 119 $entityManager->persist($connection);
117 $entityManager->persist($article); 120 $entityManager->persist($article);
121 $entityManager->persist($menu_paths);
118 $entityManager->persist($edit_page); 122 $entityManager->persist($edit_page);
119 $entityManager->persist($new_page); 123 $entityManager->persist($new_page);
120 $entityManager->persist($edit_paths);
121 $entityManager->persist($head_accueil); 124 $entityManager->persist($head_accueil);
122 $entityManager->persist($header); 125 $entityManager->persist($header);
123 $entityManager->persist($nav); 126 $entityManager->persist($nav);
@@ -127,6 +130,8 @@ function makeStartPage(EntityManager $entityManager){
127 $entityManager->persist($head_login); 130 $entityManager->persist($head_login);
128 $entityManager->persist($login); 131 $entityManager->persist($login);
129 $entityManager->persist($head_article); 132 $entityManager->persist($head_article);
133 $entityManager->persist($head_edit_menu);
134 $entityManager->persist($edit_menu);
130 $entityManager->persist($favicon); 135 $entityManager->persist($favicon);
131 $entityManager->persist($logo); 136 $entityManager->persist($logo);
132 $entityManager->persist($facebook); 137 $entityManager->persist($facebook);
@@ -137,6 +142,7 @@ function makeStartPage(EntityManager $entityManager){
137 $entityManager->persist($footer_data); 142 $entityManager->persist($footer_data);
138 $entityManager->persist($head_login_data); 143 $entityManager->persist($head_login_data);
139 $entityManager->persist($head_article_data); 144 $entityManager->persist($head_article_data);
145 $entityManager->persist($head_edit_menu_data);
140 $entityManager->flush(); 146 $entityManager->flush();
141 147
142 header('Location: ' . new URL); 148 header('Location: ' . new URL);
diff --git a/src/controller/password.php b/src/controller/password.php
index 47db637..66a617a 100644
--- a/src/controller/password.php
+++ b/src/controller/password.php
@@ -307,7 +307,7 @@ function getUser(string $login, EntityManager $entityManager): ?User
307} 307}
308 308
309 309
310function disconnect(EntityManager $entityManager) 310function disconnect()
311{ 311{
312 // nettoyage complet 312 // nettoyage complet
313 $_SESSION = []; // mémoire vive 313 $_SESSION = []; // mémoire vive
diff --git a/src/model/Position.php b/src/model/Position.php
new file mode 100644
index 0000000..74d173a
--- /dev/null
+++ b/src/model/Position.php
@@ -0,0 +1,63 @@
1<?php
2// src/modele/Position.php
3//
4// pour Node et Page
5
6declare(strict_types=1);
7
8trait Position
9{
10 public function sortChildren(bool $reposition = false): void
11 {
12 // ordre du tableau des enfants
13 // inefficace quand des noeuds ont la même position
14
15 // tri par insertion avant affichage
16 for($i = 1; $i < count($this->children); $i++)
17 {
18 $tmp = $this->children[$i];
19 $j = $i - 1;
20
21 // Déplacez les éléments du tableau qui sont plus grands que la clé
22 // à une position devant leur position actuelle
23 while ($j >= 0 && $this->children[$j]->getPosition() > $tmp->getPosition()) {
24 $this->children[$j + 1] = $this->children[$j];
25 $j = $j - 1;
26 }
27 $this->children[$j + 1] = $tmp;
28 }
29
30 foreach ($this->children as $child) {
31 if (count($child->children) > 0) {
32 $child->sortChildren($reposition);
33 }
34 }
35
36 // nouvelles positions (tableau $children => BDD)
37 if($reposition){
38 $i = 1;
39 foreach($this->children as $child){
40 $child->setPosition($i);
41 $i++;
42 }
43 }
44 }
45
46 /*private function sortChildren(): void
47 {
48 $iteration = count($this->children);
49 while($iteration > 1)
50 {
51 for($i = 0; $i < $iteration - 1; $i++)
52 {
53 if($this->children[$i]->getPosition() > $this->children[$i + 1]->getPosition())
54 {
55 $tmp = $this->children[$i];
56 $this->children[$i] = $this->children[$i + 1];
57 $this->children[$i + 1] = $tmp;
58 }
59 }
60 $iteration--;
61 }
62 }*/
63} \ No newline at end of file
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php
index a52a7e6..103163b 100644
--- a/src/model/entities/Node.php
+++ b/src/model/entities/Node.php
@@ -12,6 +12,8 @@ use Doctrine\ORM\Mapping as ORM;
12#[ORM\Table(name: TABLE_PREFIX . "node")] 12#[ORM\Table(name: TABLE_PREFIX . "node")]
13class Node 13class Node
14{ 14{
15 use \Position;
16
15 #[ORM\Id] 17 #[ORM\Id]
16 #[ORM\GeneratedValue] 18 #[ORM\GeneratedValue]
17 #[ORM\Column(type: "integer")] 19 #[ORM\Column(type: "integer")]
@@ -135,36 +137,7 @@ class Node
135 $this->children[] = $child; 137 $this->children[] = $child;
136 $this->sortChildren(false); 138 $this->sortChildren(false);
137 } 139 }
138 // utiliser $position pour afficher les éléments dans l'ordre 140
139 public function sortChildren(bool $reposition = false): void
140 {
141 // ordre du tableau des enfants
142 // inefficace quand des noeuds ont la même position
143
144 // tri par insertion
145 for($i = 1; $i < count($this->children); $i++)
146 {
147 $tmp = $this->children[$i];
148 $j = $i - 1;
149
150 // Déplacez les éléments du tableau qui sont plus grands que la clé
151 // à une position devant leur position actuelle
152 while ($j >= 0 && $this->children[$j]->getPosition() > $tmp->getPosition()) {
153 $this->children[$j + 1] = $this->children[$j];
154 $j = $j - 1;
155 }
156 $this->children[$j + 1] = $tmp;
157 }
158
159 // nouvelles positions
160 if($reposition){
161 $i = 1;
162 foreach($this->children as $child){
163 $child->setPosition($i);
164 $i++;
165 }
166 }
167 }
168 public function removeChild(self $child): void 141 public function removeChild(self $child): void
169 { 142 {
170 foreach($this->children as $key => $object){ 143 foreach($this->children as $key => $object){
diff --git a/src/model/entities/Page.php b/src/model/entities/Page.php
index c40a297..c30305c 100644
--- a/src/model/entities/Page.php
+++ b/src/model/entities/Page.php
@@ -13,6 +13,8 @@ use Doctrine\Common\Collections\ArrayCollection;
13#[ORM\Table(name: TABLE_PREFIX . "page")] 13#[ORM\Table(name: TABLE_PREFIX . "page")]
14class Page 14class Page
15{ 15{
16 use \Position;
17
16 #[ORM\Id] 18 #[ORM\Id]
17 #[ORM\GeneratedValue] 19 #[ORM\GeneratedValue]
18 #[ORM\Column(type: "integer")] 20 #[ORM\Column(type: "integer")]
@@ -56,11 +58,11 @@ class Page
56 $this->children = new ArrayCollection(); 58 $this->children = new ArrayCollection();
57 } 59 }
58 60
59 // getters 61 // getters/setters
60 /*public function getId(): int 62 public function getId(): int
61 { 63 {
62 return $this->id_page; 64 return $this->id_page;
63 }*/ 65 }
64 public function getPageName(): string 66 public function getPageName(): string
65 { 67 {
66 return $this->name_page; 68 return $this->name_page;
@@ -85,6 +87,10 @@ class Page
85 { 87 {
86 return $this->position; 88 return $this->position;
87 } 89 }
90 public function setPosition(int $position): void
91 {
92 $this->position = $position;
93 }
88 public function getParent(): ?Page 94 public function getParent(): ?Page
89 { 95 {
90 return $this->parent; 96 return $this->parent;
@@ -105,25 +111,23 @@ class Page
105 public function addChild(self $child): void 111 public function addChild(self $child): void
106 { 112 {
107 $this->children[] = $child; 113 $this->children[] = $child;
108 $this->sortChildren(); 114 $this->sortChildren(false);
109 } 115 }
110 116
111 // utiliser $position pour afficher les éléments dans l'ordre 117 public function findPageById(int $id): ?Page
112 private function sortChildren(): void
113 { 118 {
114 $iteration = count($this->children); 119 $target = null;
115 while($iteration > 1) 120 foreach($this->children as $page){
116 { 121 if($page->getId() === $id){
117 for($i = 0; $i < $iteration - 1; $i++) 122 return $page;
118 { 123 }
119 if($this->children[$i]->getPosition() > $this->children[$i + 1]->getPosition()) 124 if(count($page->getChildren()) > 0){
120 { 125 $target = $page->findPageById($id);
121 $tmp = $this->children[$i]; 126 if($target !== null){
122 $this->children[$i] = $this->children[$i + 1]; 127 return $target;
123 $this->children[$i + 1] = $tmp;
124 } 128 }
125 } 129 }
126 $iteration--;
127 } 130 }
131 return $target;
128 } 132 }
129} 133}
diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php
index 49da71c..5a7748f 100644
--- a/src/view/FooterBuilder.php
+++ b/src/view/FooterBuilder.php
@@ -29,7 +29,7 @@ class FooterBuilder extends AbstractBuilder
29 $empty_admin_zone = 'empty_admin_zone'; 29 $empty_admin_zone = 'empty_admin_zone';
30 $link_edit_page = new URL(['page' => CURRENT_PAGE, 'action' => 'modif_page']); 30 $link_edit_page = new URL(['page' => CURRENT_PAGE, 'action' => 'modif_page']);
31 $link_new_page = new URL(['from' => CURRENT_PAGE, 'page' => 'nouvelle_page']); 31 $link_new_page = new URL(['from' => CURRENT_PAGE, 'page' => 'nouvelle_page']);
32 $link_change_paths = new URL(['from' => CURRENT_PAGE, 'page' => 'menu_chemins']); 32 $link_change_paths = new URL(['page' => 'menu_chemins']);
33 33
34 $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']); 34 $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']);
35 isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : ''; 35 isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : '';
diff --git a/src/view/HeaderBuilder.php b/src/view/HeaderBuilder.php
index eef2663..28aae13 100644
--- a/src/view/HeaderBuilder.php
+++ b/src/view/HeaderBuilder.php
@@ -16,7 +16,9 @@ class HeaderBuilder extends AbstractBuilder
16 { 16 {
17 if($child->getName() === 'nav'){ 17 if($child->getName() === 'nav'){
18 $this->nav = $child; 18 $this->nav = $child;
19 // actuellement le noeud nav ne contient aucune info utile et l'envoyer à NavBuilder est inutile
19 $nav_builder = new NavBuilder($this->nav); 20 $nav_builder = new NavBuilder($this->nav);
21
20 $nav = $nav_builder->render(); 22 $nav = $nav_builder->render();
21 } 23 }
22 elseif($child->getName() === 'breadcrumb'){ 24 elseif($child->getName() === 'breadcrumb'){
diff --git a/src/view/MenuBuilder.php b/src/view/MenuBuilder.php
new file mode 100644
index 0000000..0fcfbe5
--- /dev/null
+++ b/src/view/MenuBuilder.php
@@ -0,0 +1,88 @@
1<?php
2// src/view/MenuBuilder.php
3//
4// page Menu et chemins en mode admin
5
6use App\Entity\Node;
7use App\Entity\Page;
8
9class MenuBuilder extends AbstractBuilder
10{
11 private int $margin_left_multiplier = 29;
12
13 public function __construct(Node $node)
14 {
15 parent::__construct($node);
16 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
17
18 if(file_exists($viewFile))
19 {
20 /*if(!empty($node->getNodeData()->getData()))
21 {
22 extract($node->getNodeData()->getData());
23 }*/
24
25 // ajouter un article
26 $new_article = '';
27 if($_SESSION['admin'])
28 {
29 $this->unfoldMenu(Director::$menu_data, 0 - $this->margin_left_multiplier);
30 }
31 else{
32 header('Location: ' . new URL);
33 die;
34 }
35
36 ob_start();
37 require $viewFile;
38 $this->html = ob_get_clean(); // pas de concaténation ici, on écrase
39 }
40 }
41
42 private function unfoldMenu(Page $menu, int $margin_left): void
43 {
44 $margin_left += $this->margin_left_multiplier;
45 $this->html .= '<div class="level">' . "\n";
46
47 foreach($menu->getChildren() as $entry)
48 {
49 $div_style = 'margin-left: ' . $margin_left . 'px;';
50 $checked = $entry->IsInMenu() ? 'checked' : '';
51 $this->html .= '<div id="' . $entry->getId() . '" style="' . $div_style . '">
52 <img class="move_entry_icon" onclick="" src="assets/arrow-left.svg">
53 <img class="move_entry_icon" onclick="" src="assets/arrow-right.svg">
54 <img class="move_entry_icon" onclick="switchMenuPositions(' . $entry->getId() . ', \'up\')" src="assets/arrow-up.svg">
55 <img class="move_entry_icon" onclick="switchMenuPositions(' . $entry->getId() . ', \'down\')" src="assets/arrow-down.svg">
56 <span class="menu_entry_checkbox">
57 <input type="checkbox" ' . $checked . ' onclick="checkMenuEntry(' . $entry->getId() . ')">
58 </span>
59 <button>' . $entry->getPageName() . '</button>';
60
61 if(str_starts_with($entry->getEndOfPath(), 'http')){
62 $this->html .= '<span id="edit-i..."><img class="move_entry_icon" src="assets/edit.svg" onclick="openEditor(\'i...\')"></span>
63 <i>' . $entry->getEndOfPath() . '</i>
64 <span id="delete-i..."><img class="move_entry_icon" src="assets/delete-bin.svg" onclick="delete(\'i...\')"></span>';
65 }
66 else{
67 $this->html .= '<i>' . $entry->getPagePath() . '</i>';
68 }
69
70
71 // supprimer me label "visible" et griser le texte et bouton en JS à la place
72
73 /*
74 => flèche gauche: position = position du parent + 1, parent = grand-parent, recalculer les positions
75 => flèche droite: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent
76 => flèches haut et bas: inversement de position, comme pour les noeuds, mais dans la table page
77 => checkbox: in_menu ^= 1
78 */
79
80 if(count($entry->getChildren()) > 0){
81 $this->unfoldMenu($entry, $margin_left);
82 }
83 $this->html .= '</div>' . "\n";
84 }
85 $this->html .= "</div>\n";
86 $margin_left -= $this->margin_left_multiplier;
87 }
88} \ No newline at end of file
diff --git a/src/view/NavBuilder.php b/src/view/NavBuilder.php
index 603fcfa..2718569 100644
--- a/src/view/NavBuilder.php
+++ b/src/view/NavBuilder.php
@@ -1,5 +1,7 @@
1<?php 1<?php
2// src/view/NavBuilder.php 2// src/view/NavBuilder.php
3//
4// menu principal
3 5
4declare(strict_types=1); 6declare(strict_types=1);
5 7
@@ -8,10 +10,13 @@ use App\Entity\Page;
8 10
9class NavBuilder extends AbstractBuilder 11class NavBuilder extends AbstractBuilder
10{ 12{
11 public function __construct(Node $node) 13 public function __construct(Node $node = null)
12 { 14 {
13 $this->html .= '<nav class="nav_main"><ul>'; 15 $this->html .= '<nav class="nav_main"><ul>';
14 $this->html .= $this->navMainHTML(Director::$menu_data, Director::$page_path->getArray()); 16 $this->html .= $this->navMainHTML(
17 Director::$menu_data,
18 // param nullable, ça retire une dépendance stricte entre NavBuilder et Director
19 Director::$page_path != null ? Director::$page_path->getArray() : []);
15 $this->html .= '</ul></nav>'; 20 $this->html .= '</ul></nav>';
16 } 21 }
17 22
diff --git a/src/view/templates/header.php b/src/view/templates/header.php
index 0bf4396..4b633a6 100644
--- a/src/view/templates/header.php
+++ b/src/view/templates/header.php
@@ -1,7 +1,7 @@
1<body> 1<body>
2 <div> 2 <div>
3 <header> 3 <header>
4 <div class="empty_nav_zone"> 4 <div id="nav_zone">
5 <?= $nav ?> 5 <?= $nav ?>
6 </div> 6 </div>
7 7
diff --git a/src/view/templates/menu.php b/src/view/templates/menu.php
new file mode 100644
index 0000000..a7f318e
--- /dev/null
+++ b/src/view/templates/menu.php
@@ -0,0 +1,15 @@
1<section class="menu">
2 <h3>Menu et chemins</h3>
3 <aside>
4 <p><img src="assets/arrow-left.svg"> remonter dans l'arbre</p>
5 <p><img src="assets/arrow-right.svg"> devenir une branche de l'élément précédent</p>
6 <p><img src="assets/arrow-up.svg"><img src="assets/arrow-down.svg"> déplacer la branche parmi celles de même niveau</p>
7 <p><input type="checkbox" checked>afficher/cacher</p>
8 </aside>
9<?= $this->html ?>
10 <div class="new_entry_buttons">
11 <p>Ajouter une nouvelle entrée dans le menu?</p>
12 <button id="new-i..." onclick="openEditor('i...')"><img class="action_icon" src="assets/edit.svg">avec une URL</button>
13 ...sinon cliquer sur Nouvelle page<img src="assets/arrow-down.svg">dans la barre jaune
14 </div>
15</section> \ No newline at end of file