generated from gitea_admin/default
Concerts
This commit is contained in:
829
README.md
829
README.md
@@ -1,5 +1,6 @@
|
|||||||
# Stack
|
# Stack
|
||||||
- NUXT 4
|
- NUXT 4
|
||||||
|
- VueJS 3.5
|
||||||
|
|
||||||
# Dev du site en local
|
# Dev du site en local
|
||||||
# NUXT
|
# NUXT
|
||||||
@@ -19,68 +20,786 @@ Créer un vrai /security.txt (ou /.well-known/security.txt) au lieu de le renvoy
|
|||||||
location = /security.txt { return 404; }
|
location = /security.txt { return 404; }
|
||||||
|
|
||||||
|
|
||||||
# Dev
|
# STRAPI
|
||||||
## MEDIAS QUERIES
|
## URL de PROD
|
||||||
|
bo.orchestre-ile.com
|
||||||
|
|
||||||
@media (max-width: 599px) {
|
## après modifications des fichiers src/... on rebuild strapiwww
|
||||||
. {
|
cd strapi_wondif/
|
||||||
xxx
|
NODE_ENV=production npm run build
|
||||||
}
|
pm2 list
|
||||||
|
pm2 restart strapi_wondif
|
||||||
|
pm2 list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## dev en local
|
||||||
|
- lancer MAMP pour activer la BD de STRAPI
|
||||||
|
- lancer : npm run develop
|
||||||
|
- URL de dev : http://localhost:1337
|
||||||
|
|
||||||
|
### vérifier le json de l'enpoint strapi
|
||||||
|
|
||||||
|
http://localhost:3000/api/__strapi__/concerts
|
||||||
|
http://localhost:3000/api/__strapi__/concerts?populate=*
|
||||||
|
http://localhost:3000/api/__strapi__/concerts?populate[artistes_ondif_concert][populate]=postes_artiste_ondif
|
||||||
|
http://localhost:3000/api/__strapi__/concerts?populate=*&populate[artistes_ondif_concert][populate]=postes_artiste_ondif
|
||||||
|
http://localhost:3000/api/__strapi__/concerts?populate[saison_concert]=true&populate[genre_concert]=true&populate[type_audience_concert]=true&populate[direction_ondif_concert][populate]=postes_artiste_ondif&populate[direction_invite_concert][populate]=postes_artiste_invite&populate[artistes_ondif_concert][populate]=postes_artiste_ondif&populate[artistes_invite_concert][populate]=postes_artiste_invite
|
||||||
|
|
||||||
|
API pour avoir tout de Concerts
|
||||||
|
http://localhost:3000/api/__strapi__/concerts?populate[saison_concert]=true&populate[genre_concert]=true&populate[type_audience_concert]=true&populate[direction_ondif_concert][populate]=postes_artiste_ondif&populate[direction_invite_concert][populate]=postes_artiste_invite&populate[artistes_ondif_concert][populate]=postes_artiste_ondif&populate[artistes_invite_concert][populate]=postes_artiste_invite&populate[image_illustration_concert]=true&populate[images_concert]=true&populate[videos_concert]=true&populate[audios_concert]=true&populate[programme_concert]=true&populate[representation_concert][populate]=lieu_representation&populate[liens_youtube_concert]=true
|
||||||
|
|
||||||
|
/api/__strapi__/concerts?
|
||||||
|
populate[saison_concert]=true&
|
||||||
|
populate[genre_concert]=true&
|
||||||
|
populate[type_audience_concert]=true&
|
||||||
|
populate[direction_ondif_concert][populate]=postes_artiste_ondif&
|
||||||
|
populate[direction_invite_concert][populate]=postes_artiste_invite&
|
||||||
|
populate[artistes_ondif_concert][populate]=postes_artiste_ondif&
|
||||||
|
populate[artistes_invite_concert][populate]=postes_artiste_invite&
|
||||||
|
populate[image_illustration_concert]=true&
|
||||||
|
populate[images_concert]=true&
|
||||||
|
populate[videos_concert]=true&
|
||||||
|
populate[audios_concert]=true&
|
||||||
|
populate[programme_concert]=true&
|
||||||
|
populate[representation_concert][populate]=lieu_representation&
|
||||||
|
populate[liens_youtube_concert]=true
|
||||||
|
|
||||||
|
| Niveau 1 | Niveau 2 | Niveau 3 |
|
||||||
|
|----------|----------|----------|
|
||||||
|
| saison_concert| | |
|
||||||
|
| genre_concert| | |
|
||||||
|
| type_audience_concert| | |
|
||||||
|
| direction_ondif_concert| postes_artiste_ondif| |
|
||||||
|
| direction_invite_concert|postes_artiste_invite| |
|
||||||
|
| artistes_ondif_concert| postes_artiste_ondif| |
|
||||||
|
| artistes_invite_concert| postes_artiste_invite| |
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
| A| B| C|
|
||||||
|
|
||||||
|
|
||||||
|
# CSS
|
||||||
|
## LAYOUT
|
||||||
|
|
||||||
|
@media (min-width: 0px) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
max-width: 580px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
max-width: 660px;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
max-width: 780px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
max-width: 860px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
max-width: 950px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1100px) {
|
||||||
|
max-width: 1020px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
max-width: 1100px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
max-width: 1300px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1500px) {
|
||||||
|
max-width: 1400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
## débordement = les identifier visuellement
|
||||||
|
code javascript pour mettre cette ligne outile rouge et le backgroud à tous les éléments de body pour voir les débordements
|
||||||
|
Array.from(document.querySelectorAll('body > *')).forEach(el => {
|
||||||
|
el.style.outline = '1px solid red';
|
||||||
|
el.style.backgroundColor = 'rgba(255, 0, 0, 0.3)'; // Utilisation de rgba pour une semi-transparence
|
||||||
|
});
|
||||||
|
|
||||||
|
.youtube_wp {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 70px;
|
||||||
}
|
}
|
||||||
@media (min-width: 600px) {
|
.youtube-list {
|
||||||
. {
|
display: flex;
|
||||||
xxx
|
flex-direction: column;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@media (min-width: 700px) {
|
.youtube-item {
|
||||||
. {
|
max-width: 800px;
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 800px) {
|
|
||||||
. {
|
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 900px) {
|
|
||||||
. {
|
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1000px) {
|
.youtube-item iframe {
|
||||||
. {
|
width: 100%;
|
||||||
xxx
|
|
||||||
}
|
aspect-ratio: 16 / 9;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1100px) {
|
|
||||||
. {
|
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
. {
|
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1300px) {
|
|
||||||
. {
|
|
||||||
xxx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1400px) {
|
1 sudo nano ~/.bashrc
|
||||||
. {
|
2 exit
|
||||||
xxx
|
3 ll
|
||||||
}
|
4 date
|
||||||
}
|
5 sudo ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
|
||||||
|
6 date
|
||||||
padded: { type: Boolean, default: true }, // padding vertical
|
7 cd /
|
||||||
|
8 sudo apt update
|
||||||
&--padded {
|
9 apt list --upgradable
|
||||||
padding-top: 30px;
|
10 sudo apt upgrade
|
||||||
padding-bottom: 50px;
|
11 apt list --upgradable
|
||||||
}
|
12 sudo nano /etc/ssh/sshd_config
|
||||||
|
13 sudo systemctl restart sshd
|
||||||
|
14 exit
|
||||||
|
15 sudo apt install fail2ban
|
||||||
|
16 cd /etc/fail2ban/
|
||||||
|
17 ll
|
||||||
|
18 sudo nano /etc/fail2ban/jail.conf
|
||||||
|
19 sudo service fail2ban reload
|
||||||
|
20 sudo service fail2ban status
|
||||||
|
21 sudo service fail2ban start
|
||||||
|
22 sudo service fail2ban status
|
||||||
|
23 fail2ban-client status
|
||||||
|
24 ll
|
||||||
|
25 www
|
||||||
|
26 cd /
|
||||||
|
27 ll
|
||||||
|
28 www
|
||||||
|
29 cd var
|
||||||
|
30 ll
|
||||||
|
31 date
|
||||||
|
32 cd /
|
||||||
|
33 sudo apt update
|
||||||
|
34 apt list --upgradable
|
||||||
|
35 sudo apt upgrade
|
||||||
|
36 cd /etc/fail2ban/
|
||||||
|
37 sudo service fail2ban status
|
||||||
|
38 systemctl status nginx
|
||||||
|
39 sudo apt install nginx
|
||||||
|
40 systemctl status nginx
|
||||||
|
41 sudo systemctl enable nginx
|
||||||
|
42 sudo systemctl is-enabled nginx
|
||||||
|
43 sudo nano /etc/nginx/nginx.conf
|
||||||
|
44 sudo systemctl reload nginx
|
||||||
|
45 systemctl status nginx
|
||||||
|
46 www
|
||||||
|
47 ll
|
||||||
|
48 cd ..
|
||||||
|
49 ll
|
||||||
|
50 cd www
|
||||||
|
51 ll
|
||||||
|
52 cd html/
|
||||||
|
53 ll
|
||||||
|
54 cd www
|
||||||
|
55 ll
|
||||||
|
56 www
|
||||||
|
57 ll
|
||||||
|
58 sudo mkdir wondif_2025
|
||||||
|
59 ll
|
||||||
|
60 cd wondif_2025/
|
||||||
|
61 sudo nano index.html
|
||||||
|
62 ll
|
||||||
|
63 more index.html
|
||||||
|
64 cd /etc/nginx/sites-available
|
||||||
|
65 ll
|
||||||
|
66 de default
|
||||||
|
67 more default
|
||||||
|
68 sudo nano wondif_2025
|
||||||
|
69 ll
|
||||||
|
70 more wondif_2025
|
||||||
|
71 cd /etc/nginx/sites-enabled
|
||||||
|
72 ll
|
||||||
|
73 sudo ln -s /etc/nginx/sites-available/wondif_2025 /etc/nginx/sites-enabled/
|
||||||
|
74 ll
|
||||||
|
75 sudo nginx -t
|
||||||
|
76 systemctl restart nginx
|
||||||
|
77 systemctl status nginx
|
||||||
|
78 www
|
||||||
|
79 ll
|
||||||
|
80 cd wondif_2025/
|
||||||
|
81 ll
|
||||||
|
82 pwd
|
||||||
|
83 cd /etc/nginx/sites-available
|
||||||
|
84 ll
|
||||||
|
85 more wondif_2025
|
||||||
|
86 www
|
||||||
|
87 ll
|
||||||
|
88 cd wondif_2025/
|
||||||
|
89 ll
|
||||||
|
90 sudo nano index.html
|
||||||
|
91 www
|
||||||
|
92 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
||||||
|
93 exit
|
||||||
|
94 python3 --version
|
||||||
|
95 sudo apt install certbot python3-certbot-nginx
|
||||||
|
96 cd /etc/nginx/sites-available
|
||||||
|
97 ll
|
||||||
|
98 sudo nano strapi_wondif
|
||||||
|
99 cd /etc/nginx/sites-enabled
|
||||||
|
100 ll
|
||||||
|
101 sudo ln -s /etc/nginx/sites-available/strapi_wondif /etc/nginx/sites-enabled/
|
||||||
|
102 ll
|
||||||
|
103 sudo nginx -t
|
||||||
|
104 systemctl restart nginx
|
||||||
|
105 systemctl status nginx
|
||||||
|
106 cd /etc/nginx/sites-available
|
||||||
|
107 sudo certbot --nginx -d 2025.orchestre-ile.com
|
||||||
|
108 ll
|
||||||
|
109 more wondif_2025
|
||||||
|
110 sudo certbot --nginx -d bo.orchestre-ile.com
|
||||||
|
111 ll
|
||||||
|
112 more strapi_wondif
|
||||||
|
113 sudo certbot certificates
|
||||||
|
114 sudo nginx -t
|
||||||
|
115 systemctl restart nginx
|
||||||
|
116 systemctl status nginx
|
||||||
|
117 ll
|
||||||
|
118 sudo nano wondif_2025
|
||||||
|
119 systemctl restart nginx
|
||||||
|
120 systemctl status nginx
|
||||||
|
121 www
|
||||||
|
122 nvm --version
|
||||||
|
123 nvm ls-remote
|
||||||
|
124 nvm install 22.18.0
|
||||||
|
125 node -v
|
||||||
|
126 corepack enable yarn
|
||||||
|
127 yarn -v
|
||||||
|
128 www
|
||||||
|
129 yarn global add pm2
|
||||||
|
130 pm2 start
|
||||||
|
131 pm2 list
|
||||||
|
132 cd /
|
||||||
|
133 pm2 list
|
||||||
|
134 yarn global bin
|
||||||
|
135 more ~/.bashrc
|
||||||
|
136 sudo nano ~/.bashrc
|
||||||
|
137 nano ~/.bashrc
|
||||||
|
138 source ~/.bashrc
|
||||||
|
139 pm2 start
|
||||||
|
140 pm2 list
|
||||||
|
141 mysql -u root -p
|
||||||
|
142 cd /
|
||||||
|
143 ll
|
||||||
|
144 sudo apt install gnupg
|
||||||
|
145 cd /home/debian
|
||||||
|
146 wget https://dev.mysql.com/get/mysql-apt-config_0.8.34-1_all.deb // version du 04/08/2025
|
||||||
|
147 ll
|
||||||
|
148 sudo dpkg -i mysql-apt-config*
|
||||||
|
149 apt update
|
||||||
|
150 sudo apt update --allow-insecure-repositories
|
||||||
|
151 sudo apt-get upgrade
|
||||||
|
152 sudo apt update
|
||||||
|
153 sudo apt install mysql-server
|
||||||
|
154 sudo systemctl status mysql
|
||||||
|
155 sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
|
||||||
|
156 sudo systemctl restart mysql
|
||||||
|
157 sudo systemctl status mysql
|
||||||
|
158 mysql -u root -p
|
||||||
|
159 sav
|
||||||
|
160 ll
|
||||||
|
161 sudo nano strapi_wondif
|
||||||
|
162 sudo nginx -t
|
||||||
|
163 sudo nano strapi_wondif
|
||||||
|
164 www
|
||||||
|
165 ll
|
||||||
|
166 cd strapi_wondif/
|
||||||
|
167 ll
|
||||||
|
168 rm strapi_wondif.js
|
||||||
|
169 ll
|
||||||
|
170 sav
|
||||||
|
171 ll
|
||||||
|
172 sudo nginx -t
|
||||||
|
173 more strapi_wondif
|
||||||
|
174 sudo nano strapi_wondif
|
||||||
|
175 sudo nginx -t
|
||||||
|
176 sudo nano strapi_wondif
|
||||||
|
177 systemctl restart nginx
|
||||||
|
178 systemctl status nginx
|
||||||
|
179 www
|
||||||
|
180 ll
|
||||||
|
181 cd strapi_wondif/
|
||||||
|
182 ll
|
||||||
|
183 more .env
|
||||||
|
184 www
|
||||||
|
185 ll
|
||||||
|
186 cd /var
|
||||||
|
187 ll
|
||||||
|
188 chown debian www
|
||||||
|
189 ll
|
||||||
|
190 sudo chown debian www
|
||||||
|
191 wwww
|
||||||
|
192 www
|
||||||
|
193 ll
|
||||||
|
194 yarn create strapi
|
||||||
|
195 ll
|
||||||
|
196 cd strapi_wondif/
|
||||||
|
197 ll
|
||||||
|
198 sudo nano strapi_wondif.js
|
||||||
|
199 yarn strapi_wondif start
|
||||||
|
200 ll
|
||||||
|
201 more package.json
|
||||||
|
202 NODE_OPTIONS="--max-old-space-size=2048" NODE_ENV=production yarn build
|
||||||
|
203 yarn run start
|
||||||
|
204 ll
|
||||||
|
205 pm2 start yarn --name strapi_wondif -- start
|
||||||
|
206 pm2 logs strapi_wondif
|
||||||
|
207 pm2 list
|
||||||
|
208 pm2 logs strapi_wondif
|
||||||
|
209 pm2 list
|
||||||
|
210 pm2 save
|
||||||
|
211 pm2 startup systemd
|
||||||
|
212 sudo env PATH=$PATH:/home/debian/.nvm/versions/node/v22.18.0/bin /home/debian/.config/yarn/global/node_modules/pm2/bin/pm2 startup systemd -u debian --hp /home/debian
|
||||||
|
213 pm2 list
|
||||||
|
214 ll
|
||||||
|
215 date
|
||||||
|
216 cd /
|
||||||
|
217 sudo apt update
|
||||||
|
218 sudo apt list --upgradable
|
||||||
|
219 sudo apt upgrade
|
||||||
|
220 sudo apt update
|
||||||
|
221 sudo iptables -L
|
||||||
|
222 sudo apt install fail2ban
|
||||||
|
223 cd /etc/fail2ban/
|
||||||
|
224 ls
|
||||||
|
225 ll
|
||||||
|
226 cd /var/log/fail2ban.log
|
||||||
|
227 cd /var/log/
|
||||||
|
228 ll
|
||||||
|
229 more fail2ban.log
|
||||||
|
230 fail2ban-client status
|
||||||
|
231 sudo fail2ban-client status
|
||||||
|
232 sudo apt-get install net-tools
|
||||||
|
233 netstat -a
|
||||||
|
234 ls
|
||||||
|
235 cd /
|
||||||
|
236 ls
|
||||||
|
237 cd var
|
||||||
|
238 ls
|
||||||
|
239 ll
|
||||||
|
240 cd www
|
||||||
|
241 ll
|
||||||
|
242 sav
|
||||||
|
243 ll
|
||||||
|
244 more wondif_2025
|
||||||
|
245 ll
|
||||||
|
246 sudo nano wondif_media
|
||||||
|
247 more wondif_media
|
||||||
|
248 sudo nano wondif_media
|
||||||
|
249 more wondif_media
|
||||||
|
250 cd /etc/nginx/sites-enabled
|
||||||
|
251 sudo ln -s /etc/nginx/sites-available/wondif_media /etc/nginx/sites-enabled/
|
||||||
|
252 ll
|
||||||
|
253 sudo certbot --nginx -d media.orchestre-ile.com
|
||||||
|
254 sav
|
||||||
|
255 ll
|
||||||
|
256 more wondif_media
|
||||||
|
257 sudo nginx -t
|
||||||
|
258 systemctl restart nginx
|
||||||
|
259 systemctl status nginx
|
||||||
|
260 www
|
||||||
|
261 ll
|
||||||
|
262 pm2
|
||||||
|
263 pm2 list
|
||||||
|
264 ls
|
||||||
|
265 cd strapi_wondif/
|
||||||
|
266 ll
|
||||||
|
267 pwd
|
||||||
|
268 npm install @strapi/provider-upload-aws-s3 --save
|
||||||
|
269 ls
|
||||||
|
270 ll
|
||||||
|
271 cd config/
|
||||||
|
272 ll
|
||||||
|
273 more plugins.js
|
||||||
|
274 sudo nano plugins.js
|
||||||
|
275 ll
|
||||||
|
276 cd ;;
|
||||||
|
277 cd..
|
||||||
|
278 ll
|
||||||
|
279 cd ..
|
||||||
|
280 ll
|
||||||
|
281 sudo nano .env
|
||||||
|
282 npm run build
|
||||||
|
283 npm run start
|
||||||
|
284 ll
|
||||||
|
285 pm2 list
|
||||||
|
286 pm2 restart strapi_wondif
|
||||||
|
287 ll
|
||||||
|
288 cd config/
|
||||||
|
289 ll
|
||||||
|
290 more plugins.js
|
||||||
|
291 sudo nano plugins.js
|
||||||
|
292 pm2 restart strapi_wondif
|
||||||
|
293 sudo nano plugins.js
|
||||||
|
294 sav
|
||||||
|
295 ll
|
||||||
|
296 ls
|
||||||
|
297 sudo nano strapi_wondif
|
||||||
|
298 sudo nano wondif_media
|
||||||
|
299 sudo nginx -t
|
||||||
|
300 sudo systemctl reload nginx
|
||||||
|
301 pm2 restart strapi_wondif
|
||||||
|
302 www
|
||||||
|
303 ll
|
||||||
|
304 cd strapi_wondif/
|
||||||
|
305 ll
|
||||||
|
306 cd config/
|
||||||
|
307 ll
|
||||||
|
308 sudo nano middlewares.js
|
||||||
|
309 pm2 restart strapi_wondif
|
||||||
|
310 pm2 stop strapi_wondif
|
||||||
|
311 npm run build
|
||||||
|
312 pm2 start strapi_wondif
|
||||||
|
313 www
|
||||||
|
314 ll
|
||||||
|
315 cd wondif_2025/
|
||||||
|
316 pwd
|
||||||
|
317 ll
|
||||||
|
318 sav
|
||||||
|
319 ll
|
||||||
|
320 more wondif_2025
|
||||||
|
321 www
|
||||||
|
322 ll
|
||||||
|
323 cd wondif_2025/
|
||||||
|
324 ll
|
||||||
|
325 cd ..
|
||||||
|
326 ll
|
||||||
|
327 mv wondif_2025 wondif_2025_old
|
||||||
|
328 ll
|
||||||
|
329 git clone git@git.parisweb.art:gitea_admin/wondif_vue.git
|
||||||
|
330 sudo apt update
|
||||||
|
331 sudo apt install git -y
|
||||||
|
332 git --version
|
||||||
|
333 git clone git@git.parisweb.art:gitea_admin/wondif_vue.git
|
||||||
|
334 git clone https://git.parisweb.art/gitea_admin/wondif_vue
|
||||||
|
335 ll
|
||||||
|
336 cd wondif_vue/
|
||||||
|
337 ll
|
||||||
|
338 sav
|
||||||
|
339 ll
|
||||||
|
340 sudo nano wondif_2025
|
||||||
|
341 sudo nginx -t
|
||||||
|
342 sudo systemctl reload nginx
|
||||||
|
343 www
|
||||||
|
344 ll
|
||||||
|
345 cd wondif_vue/
|
||||||
|
346 ll
|
||||||
|
347 sudo nano .env
|
||||||
|
348 npm ci
|
||||||
|
349 npm run build
|
||||||
|
350 ll
|
||||||
|
351 pm2 list
|
||||||
|
352 pm2 start npm --name "wondif_vue" -- run start
|
||||||
|
353 pm2 save
|
||||||
|
354 pm2 logs wondif_vue
|
||||||
|
355 curl http://127.0.0.1:3000
|
||||||
|
356 sav
|
||||||
|
357 ll
|
||||||
|
358 sudo nano wondif_2025
|
||||||
|
359 www
|
||||||
|
360 ll
|
||||||
|
361 cd wondif_vue/
|
||||||
|
362 ll
|
||||||
|
363 wondif_vue/
|
||||||
|
364 cat package.json
|
||||||
|
365 sudo nano package.json
|
||||||
|
366 cat package.json
|
||||||
|
367 npm run build
|
||||||
|
368 pm2 list
|
||||||
|
369 pm2 stop wondif_vue
|
||||||
|
370 pm2 start wondif_vue
|
||||||
|
371 pm2 logs wondif_vue
|
||||||
|
372 curl http://127.0.0.1:3000
|
||||||
|
373 sav
|
||||||
|
374 ll
|
||||||
|
375 more wondif_2025
|
||||||
|
376 sudo nano wondif_2025
|
||||||
|
377 sudo nginx -t
|
||||||
|
378 sudo systemctl reload nginx
|
||||||
|
379 more wondif_2025
|
||||||
|
380 www
|
||||||
|
381 ll
|
||||||
|
382 cd wondif_vue/
|
||||||
|
383 ll
|
||||||
|
384 cd public/
|
||||||
|
385 ll
|
||||||
|
386 cd img/
|
||||||
|
387 ll
|
||||||
|
388 cd photos/
|
||||||
|
389 ll
|
||||||
|
390 mv zaho_2.jpg zaho.jpg
|
||||||
|
391 ll
|
||||||
|
392 cd /var/www/wondif_vue
|
||||||
|
393 ll
|
||||||
|
394 npm ci
|
||||||
|
395 npm run build
|
||||||
|
396 pm2 restart wondif_vue
|
||||||
|
397 git pull origin main
|
||||||
|
398 rm public/img/photos/zaho.jpg
|
||||||
|
399 git pull origin main
|
||||||
|
400 npm ci
|
||||||
|
401 npm run build
|
||||||
|
402 ll
|
||||||
|
403 more .env
|
||||||
|
404 pm2 list
|
||||||
|
405 pm2 logs wondif_vue
|
||||||
|
406 cd /home/debian/.pm2/logs/
|
||||||
|
407 ll
|
||||||
|
408 more strapi-wondif-error.log
|
||||||
|
409 ll
|
||||||
|
410 truncate -s 0 strapi-wondif-error.log
|
||||||
|
411 ll
|
||||||
|
412 more strapi-wondif-out.log
|
||||||
|
413 ll
|
||||||
|
414 truncate -s 0 strapi-wondif-out.log
|
||||||
|
415 ll
|
||||||
|
416 more wondif-vue-error.log
|
||||||
|
417 ll
|
||||||
|
418 truncate -s 0 wondif-vue-error.log
|
||||||
|
419 more wondif-vue-out.log
|
||||||
|
420 ll
|
||||||
|
421 truncate -s 0 wondif-vue-out.log
|
||||||
|
422 www
|
||||||
|
423 ll
|
||||||
|
424 cd wondif_vue/
|
||||||
|
425 ll
|
||||||
|
426 cd app
|
||||||
|
427 ll
|
||||||
|
428 cd components/
|
||||||
|
429 ll
|
||||||
|
430 more header_content.vue
|
||||||
|
431 ll
|
||||||
|
432 more header_full.vue
|
||||||
|
433 ll
|
||||||
|
434 cd ..
|
||||||
|
435 ll
|
||||||
|
436 more app.vue
|
||||||
|
437 ll
|
||||||
|
438 cd pages/
|
||||||
|
439 ll
|
||||||
|
440 more index.vue
|
||||||
|
441 ll
|
||||||
|
442 more agenda.vue
|
||||||
|
443 www
|
||||||
|
444 ll
|
||||||
|
445 cd wondif_vue/
|
||||||
|
446 ll
|
||||||
|
447 cd app/
|
||||||
|
448 ll
|
||||||
|
449 cd pages/
|
||||||
|
450 ll
|
||||||
|
451 more index.vue
|
||||||
|
452 cd ..
|
||||||
|
453 ll
|
||||||
|
454 cd components/
|
||||||
|
455 ll
|
||||||
|
456 more header_full.vue
|
||||||
|
457 ll
|
||||||
|
458 more header_content.vue
|
||||||
|
459 www
|
||||||
|
460 ll
|
||||||
|
461 cd wondif_vue/
|
||||||
|
462 ll
|
||||||
|
463 sav
|
||||||
|
464 ll
|
||||||
|
465 more wondif_2025
|
||||||
|
466 sudo adduser --disabled-password --gecos "" deploy
|
||||||
|
467 sudo usermod -aG www-data deploy
|
||||||
|
468 cd /
|
||||||
|
469 ll
|
||||||
|
470 cd srv
|
||||||
|
471 ll
|
||||||
|
472 sudo ll
|
||||||
|
473 sudo ls
|
||||||
|
474 ls
|
||||||
|
475 ll
|
||||||
|
476 cd 2025
|
||||||
|
477 sudo mkdir -p /srv/apps/wondif_vue
|
||||||
|
478 ll
|
||||||
|
479 sudo chown -R deploy:deploy /srv/apps/wondif_vue
|
||||||
|
480 ll
|
||||||
|
481 sudo -u deploy ssh-keygen -t ed25519 -C "deploy@server" -f /home/deploy/.ssh/id_ed25519
|
||||||
|
482 sudo -u deploy cat /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
483 sudo -u deploy ssh -T git@git.parisweb.art
|
||||||
|
484 sudo -u deploy ssh -T gitea_admin@git.parisweb.art
|
||||||
|
485 sudo -u deploy ssh -T git@git.parisweb.art
|
||||||
|
486 sudo -u deploy ssh -T git@git.parisweb.art; echo "EXIT=$?"
|
||||||
|
487 cd /home
|
||||||
|
488 ll
|
||||||
|
489 cd deploy/
|
||||||
|
490 ll
|
||||||
|
491 sudo cd deploy/
|
||||||
|
492 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519
|
||||||
|
493 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
494 sudo -u deploy rm -f /home/deploy/.ssh/known_hosts
|
||||||
|
495 sudo -u deploy ls -la /home/deploy/.ssh
|
||||||
|
496 sudo -u deploy ls -la /home/deploy/
|
||||||
|
497 sudo -u deploy ssh-keygen -t ed25519 -C "deploy@bookstore" -f /home/deploy/.ssh/id_ed25519
|
||||||
|
498 sudo -u deploy cat /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
499 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519
|
||||||
|
500 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
501 sudo -u deploy rm -f /home/deploy/.ssh/known_hosts
|
||||||
|
502 sudo -u deploy ls -la /home/deploy/.ssh
|
||||||
|
503 sudo -u deploy ssh-keygen -t ed25519 -C "deploy@wondif_vue" -f /home/deploy/.ssh/id_ed25519
|
||||||
|
504 sudo -u deploy cat /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
505 sudo -u deploy ssh -T git@git.parisweb.art
|
||||||
|
506 sudo ss -lntp | grep -E ':22|:2222|:3000|:3022|:2200'
|
||||||
|
507 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519
|
||||||
|
508 sudo -u deploy rm -f /home/deploy/.ssh/id_ed25519.pub
|
||||||
|
509 sudo -u deploy rm -f /home/deploy/.ssh/known_hosts
|
||||||
|
510 sudo -u deploy ls -la /home/deploy/.ssh
|
||||||
|
511 sudo -u deploy nano /home/deploy/.netrc
|
||||||
|
512 sudo -u deploy more /home/deploy/.netr
|
||||||
|
513 sudo chmod 600 /home/deploy/.netrc
|
||||||
|
514 sudo chown deploy:deploy /home/deploy/.netrc
|
||||||
|
515 sudo -u deploy git ls-remote https://git.parisweb.art/gitea_admin/wondif_vue
|
||||||
|
516 cd /srv
|
||||||
|
517 ll
|
||||||
|
518 cd apps/
|
||||||
|
519 ll
|
||||||
|
520 cd wondif_vue/
|
||||||
|
521 ll
|
||||||
|
522 sudo -u deploy git clone https://git.parisweb.art/gitea_admin/wondif_vue /srv/apps/wondif_vue
|
||||||
|
523 ll
|
||||||
|
524 more .git
|
||||||
|
525 more README.md
|
||||||
|
526 cd /opt
|
||||||
|
527 ll
|
||||||
|
528 cd /var
|
||||||
|
529 ll
|
||||||
|
530 cd log/
|
||||||
|
531 ll
|
||||||
|
532 sudo mkdir -p /opt/deploy/wondif_vue /var/log/deploy
|
||||||
|
533 ll
|
||||||
|
534 sudo chown -R deploy:deploy /opt/deploy/wondif_vue /var/log/deploy
|
||||||
|
535 sudo -u deploy nano /opt/deploy/wondif_vue/deploy.sh
|
||||||
|
536 sudo chmod +x /opt/deploy/wondif_vue/deploy.sh
|
||||||
|
537 cd /opt/
|
||||||
|
538 ll
|
||||||
|
539 cd deploy/
|
||||||
|
540 ll
|
||||||
|
541 cd wondif_vue/
|
||||||
|
542 ll
|
||||||
|
543 sudo -u nano deploy.sh
|
||||||
|
544 sudo -u deploy nano deploy.sh
|
||||||
|
545 pm2 list
|
||||||
|
546 cd www
|
||||||
|
547 ll
|
||||||
|
548 www
|
||||||
|
549 ll
|
||||||
|
550 cd wondif_vue/
|
||||||
|
551 ll
|
||||||
|
552 more package.json
|
||||||
|
553 cd ..
|
||||||
|
554 ll
|
||||||
|
555 cd wondif_vue/
|
||||||
|
556 ll
|
||||||
|
557 sudo chmod +x /opt/deploy/wondif_vue/deploy.sh
|
||||||
|
558 www
|
||||||
|
559 ll
|
||||||
|
560 cd wondif_vue/
|
||||||
|
561 ll
|
||||||
|
562 git pull origin main
|
||||||
|
563 more package.json
|
||||||
|
564 more .gitignore
|
||||||
|
565 sudo nano .gitignore
|
||||||
|
566 more package.json
|
||||||
|
567 git pull origin main
|
||||||
|
568 git fetch origin
|
||||||
|
569 git reset --hard origin/main
|
||||||
|
570 git status
|
||||||
|
571 git pull origin main
|
||||||
|
572 npm ci
|
||||||
|
573 npm run build
|
||||||
|
574 ll
|
||||||
|
575 pm2 list
|
||||||
|
576 pm2 restart wondif_vue
|
||||||
|
577 pm2 describe wondif_vue
|
||||||
|
578 pm2 list
|
||||||
|
579 cd /home/debian/.pm2/logs/
|
||||||
|
580 ll
|
||||||
|
581 more wondif-vue-error.log
|
||||||
|
582 pm2 logs wondif_vue --lines 200
|
||||||
|
583 sav
|
||||||
|
584 ll
|
||||||
|
585 sudo nano wondif_2025
|
||||||
|
586 sudo nginx -t
|
||||||
|
587 sudo systemctl reload nginx
|
||||||
|
588 pm2 flush
|
||||||
|
589 pm2 list
|
||||||
|
590 pm2 logs wondif_vue --err --lines 80
|
||||||
|
591 pm2 reset wondif_vue
|
||||||
|
592 pm2 list
|
||||||
|
593 pm2 describe wondif_vue
|
||||||
|
594 pm2 logs wondif_vue
|
||||||
|
595 www
|
||||||
|
596 ll
|
||||||
|
597 cd wondif_vue
|
||||||
|
598 ll
|
||||||
|
599 git status
|
||||||
|
600 git pull origni main
|
||||||
|
601 git pull origin main
|
||||||
|
602 npm ci
|
||||||
|
603 npm run build
|
||||||
|
604 pm2 list
|
||||||
|
605 pm2 restart wondif_vue
|
||||||
|
606 git pull origin main
|
||||||
|
607 npm ci
|
||||||
|
608 git pull origin main
|
||||||
|
609 npm run build
|
||||||
|
610 pm2 restart wondif_vue
|
||||||
|
611 npx strapi version
|
||||||
|
612 ll
|
||||||
|
613 cd ..
|
||||||
|
614 ll
|
||||||
|
615 cd strapi_wondif/
|
||||||
|
616 ll
|
||||||
|
617 more README.md
|
||||||
|
618 npx strapi version
|
||||||
|
619 pm2 list
|
||||||
|
620 pm2 stop strapi_wondif
|
||||||
|
621 npx @strapi/upgrade latest
|
||||||
|
622 npx strapi version
|
||||||
|
623 NODE_ENV=production npm run build
|
||||||
|
624 pm2 list
|
||||||
|
625 pm2 start strapi_wondif
|
||||||
|
626 pm2 list
|
||||||
|
627 mysql --version
|
||||||
|
628 mysql -u root -p
|
||||||
|
629 pm2 list
|
||||||
|
630 www
|
||||||
|
631 ll
|
||||||
|
632 cd strapi_wondif/
|
||||||
|
633 ll
|
||||||
|
634 NODE_ENV=production npm run build
|
||||||
|
635 pm2 list
|
||||||
|
636 pm2 restart strapi_wondif
|
||||||
|
637 pm2 list
|
||||||
|
638 cd strapi_wondif/
|
||||||
|
639 www
|
||||||
|
640 cd strapi_wondif/
|
||||||
|
641 NODE_ENV=production npm run build
|
||||||
|
642 pm2 list
|
||||||
|
643 pm2 restart strapi_wondif
|
||||||
|
644 pm2 list
|
||||||
|
645 date
|
||||||
|
646 mysql -u root -p
|
||||||
|
647 SHOW VARIABLES LIKE '%time_zone%';
|
||||||
|
648 SHOW VARIABLES LIKE '%time_zone%'; SELECT @@global.time_zone, @@session.time_zone;
|
||||||
|
649 SELECT NOW() AS now_local, UTC_TIMESTAMP() AS now_utc, TIMEDIFF(NOW(), UTC_TIMESTAMP()) AS diff;
|
||||||
|
650 show databeses
|
||||||
|
651 show databeses;
|
||||||
|
652 history
|
||||||
@@ -22,12 +22,17 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
border-bottom: none !important;
|
||||||
.header_nav_topbar_submenu {
|
.header_nav_topbar_submenu {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
/* Pour l'effet de transition */
|
/* Pour l'effet de transition */
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.is-active {
|
||||||
|
border-bottom: 2px solid var(--c-brand_rouge);
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.header_nav_topbar_submenu {
|
.header_nav_topbar_submenu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -184,12 +189,19 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
border-bottom: none !important;
|
||||||
|
padding-bottom: 2px;
|
||||||
.header_nav_sub_menu {
|
.header_nav_sub_menu {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
/* Pour l'effet de transition */
|
/* Pour l'effet de transition */
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.is-active {
|
||||||
|
border-bottom: 2px solid var(--c-brand_rouge);
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
|
|
||||||
@@ -219,25 +231,36 @@
|
|||||||
|
|
||||||
.header_nav_sub_menu {
|
.header_nav_sub_menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
|
||||||
|
@media (min-width: 0px) {
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
visibility:hidden;
|
visibility:hidden;
|
||||||
/* Pour l'effet de transition */
|
/* Pour l'effet de transition */
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: visibility 0.2s,opacity 0.2s cubic-bezier(0.4, 0, 1, 1);
|
transition: visibility 0.2s,opacity 0.2s cubic-bezier(0.4, 0, 1, 1);
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-left: 25px;
|
padding-left: 20px;
|
||||||
padding-right: 22px;
|
padding-right: 7px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background-color: rgba(255, 255, 255, 0.93);
|
background-color: rgba(255, 255, 255, 0.97);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
.header_nav_sub_menu_item {
|
.header_nav_sub_menu_item {
|
||||||
list-style: circle;
|
list-style: circle;
|
||||||
//font-family: 'brandontext_regular';
|
//font-family: 'brandontext_regular';
|
||||||
font-family: var(--font-roboto);
|
font-family: var(--font-roboto);
|
||||||
font-size: 18px;
|
@media (min-width: 0px) {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
&:hover {
|
&:hover {
|
||||||
a {
|
a {
|
||||||
@@ -411,6 +434,7 @@
|
|||||||
|
|
||||||
.header_drawer_link {
|
.header_drawer_link {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: fit-content;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $blanc;
|
color: $blanc;
|
||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
@@ -426,6 +450,11 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.is-active {
|
||||||
|
border-bottom: 2px solid var(--c-brand_rouge);
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.header_drawer_sub_menu {
|
.header_drawer_sub_menu {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
}
|
}
|
||||||
.page-enter-active,
|
.page-enter-active,
|
||||||
.page-leave-active {
|
.page-leave-active {
|
||||||
transition: all 0.4s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
.page-enter-from,
|
.page-enter-from,
|
||||||
.page-leave-to {
|
.page-leave-to {
|
||||||
|
|||||||
117
app/components/Breadcrumb.vue
Normal file
117
app/components/Breadcrumb.vue
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="items.length > 1" aria-label="Fil d’Ariane" class="breadcrumb">
|
||||||
|
<ul class="breadcrumb__list">
|
||||||
|
<li v-for="(item, i) in items" :key="item.to" class="breadcrumb__item">
|
||||||
|
<NuxtLink v-if="i < items.length - 1" :to="item.to">
|
||||||
|
<img
|
||||||
|
v-if="i === 0"
|
||||||
|
src="/img/icones/house-grey.svg"
|
||||||
|
alt="Accueil"
|
||||||
|
class="breadcrumb__home-icon"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ item.label }}</span>
|
||||||
|
</NuxtLink>
|
||||||
|
<span v-else aria-current="page">{{ item.label }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
currentLabel: { type: String, default: '' } // utile pour les pages dynamiques
|
||||||
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const labelMap = {
|
||||||
|
concerts: 'Concerts',
|
||||||
|
agenda: 'Agenda',
|
||||||
|
saison: 'Saison',
|
||||||
|
orchestre: "L'Orchestre",
|
||||||
|
professionnels: "Professionnels"
|
||||||
|
}
|
||||||
|
|
||||||
|
function humanize(segment) {
|
||||||
|
return segment
|
||||||
|
.replace(/-/g, ' ')
|
||||||
|
.replace(/\b\w/g, (m) => m.toUpperCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = computed(() => {
|
||||||
|
const parts = route.path.split('/').filter(Boolean)
|
||||||
|
const crumbs = [{ to: '/', label: 'Accueil' }]
|
||||||
|
|
||||||
|
let acc = ''
|
||||||
|
parts.forEach((part, index) => {
|
||||||
|
acc += `/${part}`
|
||||||
|
const isLast = index === parts.length - 1
|
||||||
|
const label = isLast && props.currentLabel
|
||||||
|
? props.currentLabel
|
||||||
|
: (labelMap[part] || humanize(decodeURIComponent(part)))
|
||||||
|
|
||||||
|
crumbs.push({ to: acc, label })
|
||||||
|
})
|
||||||
|
|
||||||
|
return crumbs
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.breadcrumb {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: var(--font-roboto);
|
||||||
|
font-weight: var(--fw-extralight);
|
||||||
|
color: #6D798A;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
@media (min-width: 0px) {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.breadcrumb__list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.breadcrumb__item { display: inline-flex; align-items: center; }
|
||||||
|
.breadcrumb a {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.breadcrumb__item:not(:last-child)::after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
margin-left: 8px;
|
||||||
|
background: url('/img/icones/angle-right-grey.svg') no-repeat center / contain;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
top: -1px; /* ajuste entre 0 et 2px selon ton rendu */
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.breadcrumb__home-icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
max-width: 210px;
|
max-width: 210px;
|
||||||
}
|
}
|
||||||
@media (min-width: 300px) {
|
@media (min-width: 300px) {
|
||||||
max-width: 290px;
|
max-width: 250px;
|
||||||
}
|
}
|
||||||
@media (min-width: 400px) {
|
@media (min-width: 400px) {
|
||||||
max-width: 390px;
|
max-width: 390px;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<!-- Meta : date + lieu -->
|
<!-- Meta : date + lieu -->
|
||||||
<div class="concert-card__meta">
|
<div class="concert-card__meta">
|
||||||
<DsHeading as="h5" tone="default">
|
<DsHeading as="h5" tone="default">
|
||||||
{{ venue }}
|
{{ lieu }}
|
||||||
</DsHeading>
|
</DsHeading>
|
||||||
<DsHeading as="h6" tone="default">
|
<DsHeading as="h6" tone="default">
|
||||||
<time :datetime="dateISO">{{ dateLabel }}</time>
|
<time :datetime="dateISO">{{ dateLabel }}</time>
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<div class="concert-card__actions">
|
<div class="concert-card__actions">
|
||||||
<DsButtonArrow :to="`/concerts/${id}`" variant="secondary">
|
<DsButtonArrow :to="`${href}`" variant="secondary">
|
||||||
Réserver
|
Découvrir
|
||||||
</DsButtonArrow>
|
</DsButtonArrow>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,12 +49,13 @@
|
|||||||
defineProps({
|
defineProps({
|
||||||
id: { type: [String, Number], required: true },
|
id: { type: [String, Number], required: true },
|
||||||
title: { type: String, required: true },
|
title: { type: String, required: true },
|
||||||
venue: { type: String, required: true },
|
lieu: { type: String, required: true },
|
||||||
dateISO: { type: String, required: true }, // ex: "2026-01-15T20:00:00+01:00"
|
dateISO: { type: String, required: true }, // ex: "2026-01-15T20:00:00+01:00"
|
||||||
dateLabel: { type: String, required: true }, // ex: "Jeu. 15 jan. 2026 — 20h"
|
dateLabel: { type: String, required: true }, // ex: "Jeu. 15 jan. 2026 — 20h"
|
||||||
description: { type: String, default: '' },
|
description: { type: String, default: '' },
|
||||||
imageUrl: { type: String, default: '' },
|
imageUrl: { type: String, default: '' },
|
||||||
imageAlt: { type: String, default: '' },
|
imageAlt: { type: String, default: '' },
|
||||||
|
href: { type: String, default: '' },
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,47 @@
|
|||||||
|
<!-- app/components/concert/ConcertCardList.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div class="concert-card-list">
|
<div
|
||||||
|
class="concert-card-list"
|
||||||
|
:class="{
|
||||||
|
'concert-card-list--highlight-first': highlightFirst,
|
||||||
|
'concert-card-list--limit-cards': limitCardsOnBreakpoint,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
highlightFirst: { type: Boolean, default: true },
|
||||||
|
limitCardsOnBreakpoint: { type: Boolean, default: true },
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.concert-card-list {
|
.concert-card-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: var(--gap-cards);
|
gap: var(--gap-cards);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
.concert-card {
|
||||||
|
max-width: 452px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Afficher seulement 1 cards < 600px
|
// Afficher seulement 1 cards < 600px
|
||||||
@media (max-width: 599px) {
|
@media (max-width: 599px) {
|
||||||
.concert-card-list > .concert-card:nth-child(2) {
|
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(2) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.concert-card-list > .concert-card:nth-child(3) {
|
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(3) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Afficher seulement 2 cards < 900px
|
// Afficher seulement 2 cards < 900px
|
||||||
@media (max-width: 899px) {
|
@media (max-width: 899px) {
|
||||||
.concert-card-list > .concert-card:nth-child(3) {
|
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(3) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +57,7 @@
|
|||||||
.concert-card-list > .concert-card {
|
.concert-card-list > .concert-card {
|
||||||
flex: 1 1 260px;
|
flex: 1 1 260px;
|
||||||
}
|
}
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 280px;
|
flex: 2 1 280px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +65,7 @@
|
|||||||
.concert-card-list > .concert-card {
|
.concert-card-list > .concert-card {
|
||||||
flex: 1 1 280px;
|
flex: 1 1 280px;
|
||||||
}
|
}
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 300px;
|
flex: 2 1 300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +73,7 @@
|
|||||||
.concert-card-list > .concert-card {
|
.concert-card-list > .concert-card {
|
||||||
flex: 1 1 280px;
|
flex: 1 1 280px;
|
||||||
}
|
}
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 300px;
|
flex: 2 1 300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +82,7 @@
|
|||||||
flex: 1 1 260px;
|
flex: 1 1 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 300px;
|
flex: 2 1 300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +92,7 @@
|
|||||||
flex: 1 1 280px;
|
flex: 1 1 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 340px;
|
flex: 2 1 340px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +102,7 @@
|
|||||||
flex: 1 1 300px;
|
flex: 1 1 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 380px;
|
flex: 2 1 380px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +112,7 @@
|
|||||||
flex: 1 1 320px;
|
flex: 1 1 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 400px;
|
flex: 2 1 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +122,7 @@
|
|||||||
flex: 1 1 340px;
|
flex: 1 1 340px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 440px;
|
flex: 2 1 440px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +133,7 @@
|
|||||||
flex: 1 1 360px;
|
flex: 1 1 360px;
|
||||||
}
|
}
|
||||||
//règle spécifique après la règle générale
|
//règle spécifique après la règle générale
|
||||||
.concert-card-list > .concert-card:first-child {
|
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
|
||||||
flex: 2 1 480px;
|
flex: 2 1 480px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<HeaderNav burger-color="hamburger_black">
|
<HeaderNav burger-color="hamburger_black">
|
||||||
<template #logo>
|
<template #logo>
|
||||||
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
|
<NuxtLink to="/" aria-label="Accueil">
|
||||||
|
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
|
||||||
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #agenda-icon>
|
<template #agenda-icon>
|
||||||
@@ -44,4 +46,4 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -3,15 +3,15 @@
|
|||||||
<div class="height_10"></div>
|
<div class="height_10"></div>
|
||||||
|
|
||||||
<ul class="header_navigation_topbar" aria-label="Language selector">
|
<ul class="header_navigation_topbar" aria-label="Language selector">
|
||||||
<li class="header_nav_topbar_item">
|
<li class="header_nav_topbar_item" :class="{ 'is-active': isPro }">
|
||||||
Professionnels
|
Professionnels
|
||||||
<ul class="header_nav_topbar_submenu">
|
<ul class="header_nav_topbar_submenu">
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Programmer l'Orchestre</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/programmer-orchestre">Programmer l'Orchestre</NuxtLink></li>
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Le studio et les espaces</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/studio">Le studio et les espaces</NuxtLink></li>
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Louer des instruments</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/louer">Louer des instruments</NuxtLink></li>
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Recrutement / Concours</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/recrutement">Recrutement / Concours</NuxtLink></li>
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Espace candidats</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/candidats">Espace candidats</NuxtLink></li>
|
||||||
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Presse</NuxtLink></li>
|
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/presse">Presse</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="header_nav_topbar_item header_nav_lang">
|
<li class="header_nav_topbar_item header_nav_lang">
|
||||||
@@ -32,55 +32,56 @@
|
|||||||
<nav class="header_nav_cont" aria-label="Primary navigation">
|
<nav class="header_nav_cont" aria-label="Primary navigation">
|
||||||
<!-- Desktop nav -->
|
<!-- Desktop nav -->
|
||||||
<ul class="header_nav header_nav--desktop">
|
<ul class="header_nav header_nav--desktop">
|
||||||
<li class="header_nav_item">
|
<li class="header_nav_item" :class="{ 'is-active': isOrchestre }">
|
||||||
L'Orchestre
|
L'Orchestre
|
||||||
<ul class="header_nav_sub_menu">
|
<ul class="header_nav_sub_menu">
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/missions">Nos missions</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/direction">Direction musicale</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/musiciens">Les musiciens</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/artistes-invitees">Les artistes invités</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/discographie">Discographie</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/partenaires">Nos partenaires</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="header_nav_item">
|
<li class="header_nav_item" :class="{ 'is-active': isConcerts }">
|
||||||
Concerts
|
Concerts
|
||||||
<ul class="header_nav_sub_menu">
|
<ul class="header_nav_sub_menu">
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/saison">Saison</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/jeune-public">Jeune public</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/mode-emploi">Concert mode d'emploi</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/mag">ONDIF MAG</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/live">ONDIF LIVE !</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="header_nav_item">
|
<li class="header_nav_item" :class="{ 'is-active': isMediation }">
|
||||||
Éducation et médiation
|
Éducation et médiation
|
||||||
<ul class="header_nav_sub_menu">
|
<ul class="header_nav_sub_menu">
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/social">Champ social</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/insertion-pro">Insertion professionnelle</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/amateurs">Pratiques amateurs</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/ressources-pedagogiques">Ressources pédagogiques</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="header_nav_item">
|
<li class="header_nav_item" :class="{ 'is-active': isMecenat }">
|
||||||
Mécénat
|
Mécénat
|
||||||
<ul class="header_nav_sub_menu">
|
<ul class="header_nav_sub_menu">
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/entreprises">Entreprises</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/projets">Les projets</NuxtLink></li>
|
||||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/particuliers">Particuliers</NuxtLink></li>
|
||||||
|
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/mecenes">Ils nous font confiance</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="header_nav_item header_nav_icones">
|
<li class="header_nav_item header_nav_icones">
|
||||||
<div class="">
|
<div class="">
|
||||||
<NuxtLink to="/agenda">
|
<NuxtLink to="/concerts/agenda">
|
||||||
<div class="nav_icone">
|
<div class="nav_icone">
|
||||||
<div class="nav_icone_img nav_icone_img--agenda">
|
<div class="nav_icone_img nav_icone_img--agenda">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
@@ -91,7 +92,7 @@
|
|||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class=" padding_top_1">
|
<div class=" padding_top_1">
|
||||||
<NuxtLink to="/agenda">
|
<NuxtLink to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer">
|
||||||
<div class="nav_icone">
|
<div class="nav_icone">
|
||||||
<div class="nav_icone_img nav_icone_img--ticket">
|
<div class="nav_icone_img nav_icone_img--ticket">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
@@ -124,7 +125,7 @@
|
|||||||
<!-- Mobile icons -->
|
<!-- Mobile icons -->
|
||||||
<div class="header_nav header_nav--mobile-icons">
|
<div class="header_nav header_nav--mobile-icons">
|
||||||
<div class="header_nav_item">
|
<div class="header_nav_item">
|
||||||
<NuxtLink to="/agenda">
|
<NuxtLink to="/concerts/agenda">
|
||||||
<div class="nav_icone">
|
<div class="nav_icone">
|
||||||
<div class="nav_icone_img nav_icone_img--agenda">
|
<div class="nav_icone_img nav_icone_img--agenda">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
@@ -136,7 +137,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header_nav_item padding_top_1">
|
<div class="header_nav_item padding_top_1">
|
||||||
<NuxtLink to="/agenda">
|
<NuxtLink to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer">
|
||||||
<div class="nav_icone">
|
<div class="nav_icone">
|
||||||
<div class="nav_icone_img nav_icone_img--ticket">
|
<div class="nav_icone_img nav_icone_img--ticket">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
@@ -157,33 +158,33 @@
|
|||||||
<ul class="header_drawer_inner">
|
<ul class="header_drawer_inner">
|
||||||
<li
|
<li
|
||||||
class="header_drawer_link"
|
class="header_drawer_link"
|
||||||
:class="{ 'is-open': activeDrawer === 'orchestre' }"
|
:class="{ 'is-open': activeDrawer === 'orchestre','is-active': isOrchestre }"
|
||||||
@click="toggleDrawer('orchestre')"
|
@click="toggleDrawer('orchestre')"
|
||||||
>
|
>
|
||||||
L'Orchestre
|
L'Orchestre
|
||||||
<ul class="header_drawer_sub_menu">
|
<ul class="header_drawer_sub_menu">
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/missions">Nos missions</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/direction">Direction musicale</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/musiciens">Les musiciens</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/artistes-invitees">Les artistes invités</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/discographie">Discographie</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/partenaires">Nos partenaires</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="header_drawer_link"
|
class="header_drawer_link"
|
||||||
:class="{ 'is-open': activeDrawer === 'concerts' }"
|
:class="{ 'is-open': activeDrawer === 'concerts','is-active': isConcerts }"
|
||||||
@click="toggleDrawer('concerts')"
|
@click="toggleDrawer('concerts')"
|
||||||
>
|
>
|
||||||
Concerts
|
Concerts
|
||||||
<ul class="header_drawer_sub_menu">
|
<ul class="header_drawer_sub_menu">
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/saison">Saison</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/jeune-public">Jeune public</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/mode-emploi">Concert mode d'emploi</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/mag">ONDIF MAG</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/live">ONDIF LIVE !</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -194,12 +195,12 @@
|
|||||||
>
|
>
|
||||||
Éducation et médiation
|
Éducation et médiation
|
||||||
<ul class="header_drawer_sub_menu">
|
<ul class="header_drawer_sub_menu">
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/social">Champ social</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/insertion-pro">Insertion professionnelle</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/amateurs">Pratiques amateurs</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/ressources-pedagogiques">Ressources pédagogiques</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -210,20 +211,21 @@
|
|||||||
>
|
>
|
||||||
Mécénat
|
Mécénat
|
||||||
<ul class="header_drawer_sub_menu">
|
<ul class="header_drawer_sub_menu">
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/entreprises">Entreprises</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/projets">Les projets</NuxtLink></li>
|
||||||
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/particuliers">Particuliers</NuxtLink></li>
|
||||||
|
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/mecenes">Ils nous font confiance</NuxtLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li class="icon_mobile">
|
<li class="icon_mobile">
|
||||||
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/agenda" @click="close">
|
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/concerts/agenda" @click="close">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
<slot name="mobile_agenda_icon" />
|
<slot name="mobile_agenda_icon" />
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="/agenda" @click="close">
|
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer" @click="close">
|
||||||
<!-- ICÔNE injectée -->
|
<!-- ICÔNE injectée -->
|
||||||
<slot name="mobile_ticket" />
|
<slot name="mobile_ticket" />
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
@@ -241,12 +243,16 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
const route = useRoute()
|
||||||
import { watch } from 'vue'
|
import { watch } from 'vue'
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
burgerColor: { type: String, default: 'hamburger_black' }
|
burgerColor: { type: String, default: 'hamburger_black' }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
// MENU MOBILE
|
||||||
|
/////////////////////////////////
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
const activeDrawer = ref(null)
|
const activeDrawer = ref(null)
|
||||||
const toggle = () => (isOpen.value = !isOpen.value)
|
const toggle = () => (isOpen.value = !isOpen.value)
|
||||||
@@ -256,11 +262,38 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ✅ ferme automatiquement le mobile drawer si on navigue
|
// ✅ ferme automatiquement le mobile drawer si on navigue
|
||||||
const route = useRoute()
|
|
||||||
watch(() => route.fullPath, () => {
|
watch(() => route.fullPath, () => {
|
||||||
close()
|
close()
|
||||||
activeDrawer.value = null
|
activeDrawer.value = null
|
||||||
})
|
})
|
||||||
|
/////////////////////////////////
|
||||||
|
// MENU ACTIF
|
||||||
|
/////////////////////////////////
|
||||||
|
// L'Orchestre
|
||||||
|
const isOrchestre = computed(() =>
|
||||||
|
route.path.startsWith('/orchestre')
|
||||||
|
)
|
||||||
|
|
||||||
|
// Concerts
|
||||||
|
const isConcerts = computed(() =>
|
||||||
|
route.path.startsWith('/concerts')
|
||||||
|
)
|
||||||
|
|
||||||
|
// Éducation et médiation
|
||||||
|
const isMediation = computed(() =>
|
||||||
|
route.path.startsWith('/mediation')
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mécénat
|
||||||
|
const isMecenat = computed(() =>
|
||||||
|
route.path.startsWith('/mecenat')
|
||||||
|
)
|
||||||
|
// professionnels
|
||||||
|
const isPro = computed(() =>
|
||||||
|
route.path.startsWith('/professionnels')
|
||||||
|
)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
size: { type: String, default: 'default' }, // default / wide / narrow
|
size: { type: String, default: 'default' }, // default / wide / narrow
|
||||||
padb : { type: String, default: '' },
|
padb : { type: String, default: '' },
|
||||||
padt : { type: String, default: '' },
|
padt : { type: String, default: '' },
|
||||||
position : { type: String, dafault : ''}
|
position : { type: String, dafault : ''},
|
||||||
|
overflow : { type: String, default: '' }
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -39,9 +40,6 @@
|
|||||||
&--default {
|
&--default {
|
||||||
/* mobile / small screens */
|
/* mobile / small screens */
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
|
||||||
//padding-inline: var(--page-padding-mobile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 0px) {
|
@media (min-width: 0px) {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|||||||
91
app/components/strapiconvert/StrapiBlockChildsConvert.vue
Normal file
91
app/components/strapiconvert/StrapiBlockChildsConvert.vue
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<component v-if="isText && hasTextValue && wrapTag" :is="wrapTag">
|
||||||
|
{{ textValue }}
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<template v-else-if="isText && hasTextValue">
|
||||||
|
{{ textValue }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<component v-else-if="isList" :is="listTag">
|
||||||
|
<StrapiBlockChildsConvert
|
||||||
|
v-for="(child, i) in children"
|
||||||
|
:key="i"
|
||||||
|
:node="child"
|
||||||
|
/>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<li v-else-if="isListItem">
|
||||||
|
<StrapiBlockChildsConvert
|
||||||
|
v-for="(child, i) in children"
|
||||||
|
:key="i"
|
||||||
|
:node="child"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<a
|
||||||
|
v-else-if="isLink"
|
||||||
|
:href="href"
|
||||||
|
class="strapi-inline__link"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<StrapiBlockChildsConvert
|
||||||
|
v-for="(child, i) in children"
|
||||||
|
:key="i"
|
||||||
|
:node="child"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<StrapiBlockChildsConvert
|
||||||
|
v-for="(child, i) in children"
|
||||||
|
:key="i"
|
||||||
|
:node="child"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
node: { type: Object, required: true },
|
||||||
|
})
|
||||||
|
|
||||||
|
const isText = computed(() => props.node?.type === 'text')
|
||||||
|
const isLink = computed(() => props.node?.type === 'link')
|
||||||
|
const isList = computed(() => props.node?.type === 'list')
|
||||||
|
const isListItem = computed(() => props.node?.type === 'list-item')
|
||||||
|
const children = computed(() => props.node?.children || [])
|
||||||
|
const listTag = computed(() => (
|
||||||
|
props.node?.format === 'ordered' ? 'ol' : 'ul'
|
||||||
|
))
|
||||||
|
|
||||||
|
const textValue = computed(() => (props.node?.text ?? '').toString())
|
||||||
|
const hasTextValue = computed(() => textValue.value.length > 0)
|
||||||
|
|
||||||
|
// Dans Strapi blocks, les liens peuvent être "url" ou "href" selon les versions/plugins
|
||||||
|
const href = computed(() => props.node?.url || props.node?.href || '#')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gestion des "marks" (bold/italic/underline/...)
|
||||||
|
* Ici on choisit une stratégie simple : UN seul wrapper.
|
||||||
|
* -> si tu veux combiner plusieurs marks (bold + italic), on le fait après.
|
||||||
|
*/
|
||||||
|
const wrapTag = computed(() => {
|
||||||
|
const n = props.node || {}
|
||||||
|
if (!isText.value) return null
|
||||||
|
|
||||||
|
if (n.code) return 'code'
|
||||||
|
if (n.bold) return 'strong'
|
||||||
|
if (n.italic) return 'em'
|
||||||
|
if (n.underline) return 'u'
|
||||||
|
if (n.strikethrough) return 's'
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
222
app/components/strapiconvert/StrapiBlocksConvert.vue
Normal file
222
app/components/strapiconvert/StrapiBlocksConvert.vue
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<template>
|
||||||
|
<div class="strapi-blocks">
|
||||||
|
<template v-for="(block, i) in blocks" :key="i">
|
||||||
|
|
||||||
|
<!-- Paragraph -->
|
||||||
|
<p v-if="block.type === 'paragraph'" class="strapi-blocks--p">
|
||||||
|
<template v-for="(child, j) in (block.children)" :key="j">
|
||||||
|
<StrapiBlockChildsConvert :node="child" />
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Heading -->
|
||||||
|
<component
|
||||||
|
v-else-if="block.type === 'heading'"
|
||||||
|
:is="`h${block.level}`"
|
||||||
|
class="strapi-blocks__h"
|
||||||
|
>
|
||||||
|
<template v-for="(child, j) in (block.children)" :key="j">
|
||||||
|
<StrapiBlockChildsConvert :node="child" />
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<!-- Quote -->
|
||||||
|
<blockquote
|
||||||
|
v-else-if="block.type === 'quote'"
|
||||||
|
>
|
||||||
|
<template v-for="(child, j) in (block.children)" :key="j">
|
||||||
|
<StrapiBlockChildsConvert :node="child" />
|
||||||
|
</template>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<!-- Lists -->
|
||||||
|
<ul
|
||||||
|
v-else-if="block.type === 'list' && block.format === 'unordered'"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(item, j) in normalizeListItems(block.children)"
|
||||||
|
:key="j"
|
||||||
|
>
|
||||||
|
<template v-for="(child, k) in (item.children)" :key="k">
|
||||||
|
<StrapiBlockChildsConvert :node="child" />
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ol
|
||||||
|
v-else-if="block.type === 'list' && block.format === 'ordered'"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(item, j) in normalizeListItems(block.children)"
|
||||||
|
:key="j"
|
||||||
|
>
|
||||||
|
<template v-for="(child, k) in (item.children)" :key="k">
|
||||||
|
<StrapiBlockChildsConvert :node="child" />
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<!-- Fallback -->
|
||||||
|
<div v-else class="strapi-blocks--unknown">
|
||||||
|
<!-- debug éventuel -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import StrapiBlockChildsConvert from './StrapiBlockChildsConvert.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
blocks: { type: Array, default: () => [] },
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeListItems = (children = []) => {
|
||||||
|
const normalized = []
|
||||||
|
|
||||||
|
for (const child of children) {
|
||||||
|
if (!child || typeof child !== 'object') continue
|
||||||
|
|
||||||
|
if (child.type === 'list-item') {
|
||||||
|
normalized.push({
|
||||||
|
...child,
|
||||||
|
children: Array.isArray(child.children) ? [...child.children] : [],
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Certains contenus Strapi placent une sous-liste comme sibling d'un list-item.
|
||||||
|
// On la rattache au dernier list-item pour produire un HTML imbriqué valide.
|
||||||
|
if (child.type === 'list' && normalized.length > 0) {
|
||||||
|
normalized[normalized.length - 1].children.push(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalized
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.strapi-blocks {
|
||||||
|
font-family: var(--font-roboto);
|
||||||
|
|
||||||
|
&--p {
|
||||||
|
|
||||||
|
font-weight: var(--fw-light);
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
padding-bottom: 7px;
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
|
font-size: 27px;
|
||||||
|
color: var(--c-brand_rouge);
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
font-weight: var(--fw-semibold);
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
padding-bottom: 3px;
|
||||||
|
font-weight: var(--fw-medium);
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
padding-bottom: 3px;
|
||||||
|
font-weight: var(--fw-medium);
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
padding-bottom: 3px;
|
||||||
|
font-weight: var(--fw-medium);
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--c-brand_rouge-weak);
|
||||||
|
text-decoration-thickness: from-font;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 0 5px;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 23px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li::before {
|
||||||
|
content: "•";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: -7px;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
/*background-image: var(--strapi-li-icon);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center;*/
|
||||||
|
font-size: 39px;
|
||||||
|
line-height: 1;
|
||||||
|
/* color: var(--c-brand_rouge); /* couleur */
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
counter-reset: item;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol > li {
|
||||||
|
counter-increment: item;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol > li::before {
|
||||||
|
content: counter(item) ". ";
|
||||||
|
}
|
||||||
|
|
||||||
|
li > ul,
|
||||||
|
li > ol {
|
||||||
|
margin-top: 4px;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > ul > li::before {
|
||||||
|
/* background-image: var(--strapi-li-icon-nested); */
|
||||||
|
content: "◦";
|
||||||
|
top: -6px;
|
||||||
|
font-size: 30px;
|
||||||
|
line-height: 1;
|
||||||
|
color: var(--c-text); /* couleur */
|
||||||
|
}
|
||||||
|
blockquote {
|
||||||
|
border-left: 11px var(--c-text-muted) solid;
|
||||||
|
padding-left: 20px;
|
||||||
|
margin-left: 2%;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Espace uniquement avant un titre s'il suit un bloc de contenu
|
||||||
|
&--p + &__h,
|
||||||
|
&--ul + &__h,
|
||||||
|
&--ol + &__h,
|
||||||
|
&--quote + &__h {
|
||||||
|
margin-top: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
128
app/composables/useConcerts.js
Normal file
128
app/composables/useConcerts.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
export function useConcerts(options = {}) {
|
||||||
|
const queryString = computed(() => {
|
||||||
|
const locale = unref(options.locale) ?? "fr-FR"
|
||||||
|
const sort = unref(options.sort) ?? null
|
||||||
|
const populate = unref(options.populate) ?? null
|
||||||
|
const filters = unref(options.filters) ?? null
|
||||||
|
|
||||||
|
const query = new URLSearchParams()
|
||||||
|
query.set("locale", locale)
|
||||||
|
if (sort) {
|
||||||
|
query.set("sort[0]", sort)
|
||||||
|
}
|
||||||
|
if (populate && typeof populate === "object") {
|
||||||
|
appendPopulate(query, populate)
|
||||||
|
}
|
||||||
|
if (filters && typeof filters === "object") {
|
||||||
|
appendFilters(query, filters)
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.toString()
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data, pending, error, refresh } = useFetch(
|
||||||
|
() => `/api/__strapi__/concerts?${queryString.value}`,
|
||||||
|
{
|
||||||
|
server: true,
|
||||||
|
key: () => `concerts:${queryString.value}`,
|
||||||
|
watch: [queryString],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const concerts = computed(() => {
|
||||||
|
const rows = (data.value?.data || []).map(normalizeConcert)
|
||||||
|
let list = rows.sort(compareByRepresentationDate)
|
||||||
|
|
||||||
|
const upcomingOnly = Boolean(unref(options.upcomingOnly) ?? false)
|
||||||
|
if (upcomingOnly) {
|
||||||
|
const todayStart = new Date()
|
||||||
|
todayStart.setHours(0, 0, 0, 0)
|
||||||
|
list = list.filter((c) => {
|
||||||
|
const d = getFirstRepresentationDate(c)
|
||||||
|
return d ? d >= todayStart : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const limit = unref(options.limit)
|
||||||
|
if (typeof limit === "number") {
|
||||||
|
list = list.slice(0, Math.max(0, limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
concerts,
|
||||||
|
pending,
|
||||||
|
error,
|
||||||
|
refresh,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendPopulate(query, populate, prefix = "populate") {
|
||||||
|
Object.entries(populate).forEach(([key, value]) => {
|
||||||
|
if (value === true) {
|
||||||
|
query.set(`${prefix}[${key}]`, "true")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value && typeof value === "object") {
|
||||||
|
const entries = Object.entries(value)
|
||||||
|
const allTrue = entries.length > 0 && entries.every(([, v]) => v === true)
|
||||||
|
if (allTrue) {
|
||||||
|
const list = entries.map(([k]) => k).join(",")
|
||||||
|
query.set(`${prefix}[${key}][populate]`, list)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appendPopulate(query, value, `${prefix}[${key}][populate]`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFilters(query, filters, prefix = "filters") {
|
||||||
|
Object.entries(filters).forEach(([key, value]) => {
|
||||||
|
if (value === null || value === undefined) return
|
||||||
|
if (typeof value !== "object") {
|
||||||
|
query.set(`${prefix}[${key}]`, String(value))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Object.entries(value).forEach(([k, v]) => {
|
||||||
|
if (v === null || v === undefined) return
|
||||||
|
if (typeof v !== "object") {
|
||||||
|
query.set(`${prefix}[${key}][${k}]`, String(v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appendFilters(query, v, `${prefix}[${key}][${k}]`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeConcert(item) {
|
||||||
|
const a = item.attributes || item || {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
...a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tri par date de représentation
|
||||||
|
function compareByRepresentationDate(a, b) {
|
||||||
|
const da = getFirstRepresentationDate(a)
|
||||||
|
const db = getFirstRepresentationDate(b)
|
||||||
|
if (!da && !db) return 0
|
||||||
|
if (!da) return 1
|
||||||
|
if (!db) return -1
|
||||||
|
return da - db
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstRepresentationDate(concert) {
|
||||||
|
const reps = concert?.representation_concert || []
|
||||||
|
let earliest = null
|
||||||
|
reps.forEach((r) => {
|
||||||
|
const iso = r?.date_debut_representation
|
||||||
|
if (!iso) return
|
||||||
|
const d = new Date(iso)
|
||||||
|
if (!earliest || d < earliest) earliest = d
|
||||||
|
})
|
||||||
|
return earliest
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ConcertCard
|
|
||||||
v-for="c in concerts"
|
|
||||||
:key="c.id"
|
|
||||||
:title="c.title"
|
|
||||||
:date-label="c.dateLabel"
|
|
||||||
:venue="c.venue"
|
|
||||||
:city="c.city"
|
|
||||||
:image="{ src: c.imageUrl, alt: c.imageAlt }"
|
|
||||||
:tags="c.tags"
|
|
||||||
:price-from="c.priceFrom"
|
|
||||||
:is-sold-out="c.soldOut"
|
|
||||||
:href="`/concerts/${c.slug}`"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
883
app/pages/concerts/[id].vue
Normal file
883
app/pages/concerts/[id].vue
Normal file
@@ -0,0 +1,883 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section v-if="pending" aria-busy="true" aria-live="polite">
|
||||||
|
<p>en cours de chargement...</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<PageSection tone="" content-size="default" class="breadcrum_wp">
|
||||||
|
<Breadcrumb :current-label="concert?.titre_concert || ''" />
|
||||||
|
</PageSection>
|
||||||
|
|
||||||
|
|
||||||
|
<section class="fiche_header_wp">
|
||||||
|
<div class="fiche_header_wp_gauche"></div>
|
||||||
|
<div class="fiche_header_wp_gauche_carre"></div>
|
||||||
|
<div class="fiche_header_inner">
|
||||||
|
<div class="fiche_header_titres">
|
||||||
|
<div>
|
||||||
|
<DsHeading as="h1" tone="default" textcase="uppercase" class="concert-card__title">
|
||||||
|
{{ concert.titre_concert }}
|
||||||
|
</DsHeading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<DsText as="p" size="md" tone="default" class="" v-if="concert.sous_titre_concert">
|
||||||
|
{{ concert.sous_titre_concert }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fiche_header_img">
|
||||||
|
<DsMedia
|
||||||
|
v-if="illustration?.url"
|
||||||
|
:src="illustration.url"
|
||||||
|
:alt="illustration.alternativeText || concert?.titre_concert || ''"
|
||||||
|
ratio="3-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="fiche_header_bandeau"></div>
|
||||||
|
<div class="fiche_header_infos">
|
||||||
|
<div>
|
||||||
|
<DsHeading as="h2" tone="invert" textcase="uppercase" class="fiche_header_infos_genre" v-if="genreLabel">
|
||||||
|
{{ genreLabel }}
|
||||||
|
</DsHeading>
|
||||||
|
</div>
|
||||||
|
<div v-if="concert.duree_concert">
|
||||||
|
<DsText as="p" tone="invert" weight="bold" spacing="space-0" class="">
|
||||||
|
DURÉE {{ concert.duree_concert }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="invert" class="" v-if="concert.duree_entracte">
|
||||||
|
Entracte {{ concert.duree_entracte }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
<div v-if="concert.production_concert">
|
||||||
|
<DsText as="p" tone="invert" class="">
|
||||||
|
{{ concert.production_concert }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fiche_header_wp_droite"></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<PageSection tone="" content-size="default">
|
||||||
|
<section class="fiche_details_wp">
|
||||||
|
<section class="distribution_wp">
|
||||||
|
<div v-if="directionsOndif.length">
|
||||||
|
<div v-for="d in directionsOndif" :key="d.id" class="distribution_item">
|
||||||
|
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_ondif?.length" class="distribution_item_poste direction">
|
||||||
|
{{ d.postes_artiste_ondif.map((p) => p.nom_poste).join(', ') }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" weight="bold" class="">
|
||||||
|
{{ d.nom_artiste_ondif }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="directionsInvite.length">
|
||||||
|
<div v-for="d in directionsInvite" :key="d.id" class="distribution_item">
|
||||||
|
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_invite?.length" class="distribution_item_poste direction">
|
||||||
|
{{ d.postes_artiste_invite.map((p) => p.nom_poste).join(', ') }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" weight="bold" class="">
|
||||||
|
{{ d.nom_artiste_invite }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="artistesOndif.length">
|
||||||
|
<div v-for="d in artistesOndif" :key="d.id" class="distribution_item">
|
||||||
|
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_ondif?.length" class="distribution_item_poste">
|
||||||
|
{{ d.postes_artiste_ondif.map((p) => p.nom_poste).join(', ') }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" class="">
|
||||||
|
{{ d.nom_artiste_ondif }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="artistesInvite.length">
|
||||||
|
<div v-for="d in artistesInvite" :key="d.id" class="distribution_item">
|
||||||
|
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_invite?.length" class="distribution_item_poste">
|
||||||
|
{{ d.postes_artiste_invite.map((p) => p.nom_poste).join(', ') }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" class="">
|
||||||
|
{{ d.nom_artiste_invite }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="programme_wp">
|
||||||
|
<div>
|
||||||
|
<DsHeading as="h2" tone="invert" textcase="uppercase" class="programme_titre">
|
||||||
|
PROGRAMME
|
||||||
|
</DsHeading>
|
||||||
|
</div>
|
||||||
|
<div class="programme_list">
|
||||||
|
<div v-for="(p, i) in programmes" :key="p.id || i" class="programme_item" >
|
||||||
|
<DsText as="p" tone="default" size="lg" spacing="space-0" weight="semibold" class="programme_compositeur">
|
||||||
|
{{ p.compositeur_programme }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" spacing="space-0" class="programme_oeuvre">
|
||||||
|
{{ p.oeuvre_programme }}
|
||||||
|
</DsText>
|
||||||
|
<DsText as="p" tone="default" size="lg" class="" v-if="p.piece_programme">
|
||||||
|
{{ p.piece_programme }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div v-if="representations.length" class="representation_wp">
|
||||||
|
<div v-for="(r, i) in representations" :key="r.id || i" class="representation_item">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<DsHeading as="h6" tone="default" v-if="r.date_debut_representation">
|
||||||
|
{{ formatDateLong(r.date_debut_representation) }} <span v-if="r.date_fin_representation">- {{ formatDateLong(r.date_fin_representation) }}</span>
|
||||||
|
</DsHeading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<DsHeading as="h5" tone="default" v-if="r.lieu_representation?.nom_lieu" class="representation_item_lieu">
|
||||||
|
{{ r.lieu_representation.nom_lieu }}
|
||||||
|
</DsHeading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<DsText as="p" tone="default" spacing="space-0" v-if="r.lieu_representation?.adresse_lieu">
|
||||||
|
{{ r.lieu_representation.adresse_lieu }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="representation_item_comment_wp">
|
||||||
|
<DsText as="p" tone="default" spacing="space-0" v-if="r.commentaire_representation" class="representation_item_comment">
|
||||||
|
{{ r.commentaire_representation }}
|
||||||
|
</DsText>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="representation_cta">
|
||||||
|
<a
|
||||||
|
v-if="r.lien_billetterie_representation"
|
||||||
|
:href="r.lien_billetterie_representation"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Réserver
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="description_wp">
|
||||||
|
<StrapiBlocksConvert :blocks="concert?.description_concert" />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<section class="img-gallery_wp">
|
||||||
|
<div v-if="imagesConcert.length" class="img-gallery">
|
||||||
|
<DsMedia
|
||||||
|
v-for="img in imagesConcert"
|
||||||
|
:key="img.id || img.url"
|
||||||
|
:src="img.url"
|
||||||
|
:alt="img.alternativeText || concert?.titre_concert || ''"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="youtube_wp">
|
||||||
|
<div v-if="youtubeEmbeds.length" class="youtube-list">
|
||||||
|
<div v-for="v in youtubeEmbeds" :key="v.id" class="youtube-item">
|
||||||
|
<iframe
|
||||||
|
:src="v.src"
|
||||||
|
title="Vidéo YouTube"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="strict-origin-when-cross-origin"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
allowfullscreen
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</PageSection>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||||
|
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||||||
|
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||||
|
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||||
|
import DsButton from '@root/design-system/primitives/DsButton.vue'
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// RÉCUPÉRATION DU CONTENU
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
const concertSlug = computed(() => String(route.params.id || ''))
|
||||||
|
const populate = {
|
||||||
|
saison_concert: true,
|
||||||
|
genre_concert: true,
|
||||||
|
type_audience_concert: true,
|
||||||
|
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
direction_invite_concert: { postes_artiste_invite: true },
|
||||||
|
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
artistes_invite_concert: { postes_artiste_invite: true },
|
||||||
|
image_illustration_concert: true,
|
||||||
|
images_concert: true,
|
||||||
|
videos_concert: true,
|
||||||
|
audios_concert: true,
|
||||||
|
programme_concert: true,
|
||||||
|
representation_concert: { lieu_representation: true },
|
||||||
|
liens_youtube_concert: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const filters = computed(() => ({
|
||||||
|
slug_concert: {
|
||||||
|
$eq: concertSlug.value,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
const { concerts, pending, error } = useConcerts({
|
||||||
|
locale: 'fr-FR',
|
||||||
|
populate,
|
||||||
|
filters,
|
||||||
|
limit: 1,
|
||||||
|
upcomingOnly: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const concert = computed(() => concerts.value?.[0] || {})
|
||||||
|
|
||||||
|
useSeoMeta({
|
||||||
|
title: () => concert.value?.titre_concert || 'Concert',
|
||||||
|
description: () => concert.value?.resume_concert || undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const genreLabel = computed(() => {
|
||||||
|
const g = concert.value?.genre_concert
|
||||||
|
|
||||||
|
// Strapi relation classique
|
||||||
|
if (Array.isArray(g?.data)) return g.data.map(x => x?.attributes?.nom_genre).filter(Boolean).join(', ')
|
||||||
|
if (g?.data) return g.data?.attributes?.nom_genre || ''
|
||||||
|
|
||||||
|
// Si déjà normalisé/flat
|
||||||
|
if (Array.isArray(g)) return g.map(x => x?.nom_genre).filter(Boolean).join(', ')
|
||||||
|
return g?.nom_genre || ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const directionsOndif = computed(() => {
|
||||||
|
const value = concert.value?.direction_ondif_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
const directionsInvite = computed(() => {
|
||||||
|
const value = concert.value?.direction_invite_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
const artistesOndif = computed(() => {
|
||||||
|
const value = concert.value?.artistes_ondif_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
const artistesInvite = computed(() => {
|
||||||
|
const value = concert.value?.artistes_invite_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
const programmes = computed(() => {
|
||||||
|
const value = concert.value?.programme_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
const representations = computed(() => {
|
||||||
|
const value = concert.value?.representation_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
|
||||||
|
const illustration = computed(() => {
|
||||||
|
const m = concert.value?.image_illustration_concert
|
||||||
|
if (!m) return null
|
||||||
|
if (m.url) return m
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
|
||||||
|
const imagesConcert = computed(() => {
|
||||||
|
const value = concert.value?.images_concert
|
||||||
|
if (!value) return []
|
||||||
|
if (Array.isArray(value) && value[0]?.url) return value
|
||||||
|
return Array.isArray(value) ? value : []
|
||||||
|
})
|
||||||
|
const youtube = computed(() => {
|
||||||
|
const value = concert.value?.liens_youtube_concert
|
||||||
|
if (!value) return []
|
||||||
|
return Array.isArray(value) ? value : [value]
|
||||||
|
})
|
||||||
|
function getYoutubeId(url = '') {
|
||||||
|
try {
|
||||||
|
const u = new URL(url)
|
||||||
|
if (u.hostname.includes('youtu.be')) return u.pathname.slice(1)
|
||||||
|
if (u.pathname.startsWith('/shorts/')) return u.pathname.split('/')[2]
|
||||||
|
if (u.pathname.startsWith('/embed/')) return u.pathname.split('/')[2]
|
||||||
|
return u.searchParams.get('v')
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const youtubeEmbeds = computed(() =>
|
||||||
|
youtube.value
|
||||||
|
.map((item) => {
|
||||||
|
const id = getYoutubeId(item?.lien_youtube)
|
||||||
|
if (!id) return null
|
||||||
|
return {
|
||||||
|
id: item.id || id,
|
||||||
|
src: `https://www.youtube-nocookie.com/embed/${id}?rel=0&modestbranding=1&iv_load_policy=3&playsinline=1`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
.breadcrum_wp {
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fiche_header_wp {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: auto 510px 20px 200px;
|
||||||
|
padding-top: 40px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-template-columns: minmax(10px, 10px) 580px 0px;
|
||||||
|
grid-template-rows: 40px 280px 20px 230px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
grid-template-columns: minmax(10px, 10px) 660px 0px;
|
||||||
|
grid-template-rows: 70px 250px 90px 300px;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
grid-template-columns: minmax(10px, 10px) 780px minmax(10px, 10px);
|
||||||
|
grid-template-rows: 60px 280px 70px 300px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
grid-template-columns: minmax(10px, 10px) 860px minmax(10px, 10px);
|
||||||
|
grid-template-rows: 90px 340px 100px 250px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 950px minmax(10px, auto);
|
||||||
|
grid-template-rows: 90px 340px 120px 270px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1100px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 1020px minmax(20px, auto);
|
||||||
|
grid-template-rows: 90px 340px 140px 290px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 1100px minmax(20px, auto);
|
||||||
|
grid-template-rows: 90px 340px 160px 330px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 1200px minmax(20px, auto);
|
||||||
|
grid-template-rows: 90px 340px 160px 330px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 1300px minmax(20px, auto);
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1500px) {
|
||||||
|
grid-template-columns: minmax(20px, auto) 1400px minmax(20px, auto);
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fiche_header_wp_gauche {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fiche_header_wp_gauche_carre {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
background-color: var(--c-backgroud-black);
|
||||||
|
}
|
||||||
|
.fiche_header_wp_droite {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fiche_header_inner {
|
||||||
|
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1/5;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1/5;
|
||||||
|
}
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-template-columns: 4fr 1fr 0.5fr;
|
||||||
|
grid-template-rows: auto 510px 20px 200px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
width: 575px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 40px 280px 20px 230px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
width: 675px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 70px 250px 90px 300px;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
width: 780px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 60px 280px 70px 300px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
width: 860px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 100px 250px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
width: 950px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 120px 270px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1100px) {
|
||||||
|
width: 1020px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 140px 290px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
width: 1100px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 330px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
width: 1200px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 330px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
width: 1300px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1500px) {
|
||||||
|
width: 1400px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
width: 1400px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1700px) {
|
||||||
|
width: 1400px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1800px) {
|
||||||
|
width: 1400px;
|
||||||
|
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||||
|
grid-template-rows: 90px 340px 160px 380px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fiche_header_titres {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
|
gap: 0.75rem;
|
||||||
|
h1 {
|
||||||
|
font-size: 55px;
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1100px) {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
font-size: 50px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1500px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1700px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1800px) {
|
||||||
|
font-size: 55px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fiche_header_img {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 2 / 4;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 3 / 5;
|
||||||
|
grid-row: 1 / 5;
|
||||||
|
}
|
||||||
|
overflow: hidden;
|
||||||
|
.ds-media {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fiche_header_infos {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-column: 1 / 2;
|
||||||
|
grid-row: 4;
|
||||||
|
margin-top: -30px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
display: grid;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: end;
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 700px) {
|
||||||
|
gap: 7px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
text-align: right;
|
||||||
|
.fiche_header_infos_genre {
|
||||||
|
font-weight: 900;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fiche_header_bandeau {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 600px) {
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
grid-row: 4;
|
||||||
|
margin-top: -30px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
background-color: var(--c-backgroud-black);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ */
|
||||||
|
/* DISTRIBUTION / PROGRAMME */
|
||||||
|
/* ============================ */
|
||||||
|
.fiche_details_wp {
|
||||||
|
.distribution_wp {
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
padding-left: 20px;
|
||||||
|
.distribution_item {
|
||||||
|
display: flex;
|
||||||
|
.distribution_item_poste {
|
||||||
|
padding-right: 10px;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
.direction {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.programme_wp {
|
||||||
|
|
||||||
|
background-color: var(--c-backgroud-brandreverse);
|
||||||
|
margin-bottom: 70px;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-right: 30px;
|
||||||
|
padding-left: 40px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
|
||||||
|
/* DÉCALAGE DU BLOC VERS LA DROITE */
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 700px) {
|
||||||
|
width: 89vw;
|
||||||
|
left: 5%;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
width: 67vw;
|
||||||
|
left: 30%;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
width: 50vw;
|
||||||
|
left: 49%;
|
||||||
|
}
|
||||||
|
transform: translateX(0px);
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-right: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
justify-content: initial;
|
||||||
|
align-items: initial;
|
||||||
|
|
||||||
|
.programme_titre {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
.programme_list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
column-gap: 20px;
|
||||||
|
row-gap: 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.programme_item {
|
||||||
|
flex: 1 0 200px;
|
||||||
|
|
||||||
|
background-color: var(--c-surface);
|
||||||
|
padding-top: 14px;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-left: 18px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ */
|
||||||
|
/* REPRÉSENTATIONS */
|
||||||
|
/* ============================ */
|
||||||
|
.representation_wp {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* justify-content: center; */
|
||||||
|
column-gap: 30px;
|
||||||
|
row-gap: 30px;
|
||||||
|
padding-bottom: 70px;
|
||||||
|
@media (min-width: 0px) and (max-width: 500px) {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.representation_item {
|
||||||
|
|
||||||
|
@media (min-width: 0px) and (max-width: 500px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
max-width: 215px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
max-width: 262px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
flex: 1 1 300px;
|
||||||
|
display: grid;
|
||||||
|
border: 2px var(--c-brand_rouge) solid;
|
||||||
|
padding-top: 20px;
|
||||||
|
> * {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.representation_item_comment_wp {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.representation_item_comment {
|
||||||
|
background-color: lightgray;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.representation_cta {
|
||||||
|
color: var(--c-surface);
|
||||||
|
background-color: var(--c-brand_rouge);
|
||||||
|
margin-top: 15px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
a {
|
||||||
|
font-family: var(--font-roboto);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ */
|
||||||
|
/* DESCRIPTION */
|
||||||
|
/* ============================ */
|
||||||
|
.description_wp {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding-bottom: 70px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
> * {
|
||||||
|
max-width: 570px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ============================ */
|
||||||
|
/* GALERIES */
|
||||||
|
/* ============================ */
|
||||||
|
|
||||||
|
.img-gallery_wp {
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-gallery {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 520px));
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-gallery > * {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-gallery :deep(.ds-media) {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-gallery :deep(.ds-media__img) {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-gallery :deep(.ds-media__img:hover) {
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
.img-gallery {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 820px) {
|
||||||
|
.img-gallery {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 520px) {
|
||||||
|
.img-gallery {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.youtube_wp {
|
||||||
|
margin-bottom: 70px;
|
||||||
|
}
|
||||||
|
.youtube-list {
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
/* flex-wrap: wrap; */
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
.youtube-item {
|
||||||
|
@media (min-width: 0px) and (max-width: 300px) {
|
||||||
|
min-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 300px) {
|
||||||
|
min-width: 298px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 400px) {
|
||||||
|
min-width: 398px;
|
||||||
|
}
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
min-width: 480px;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
min-width: 580px;
|
||||||
|
}
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
min-width: 670px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.youtube-item iframe {
|
||||||
|
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
71
app/pages/concerts/agenda.vue
Normal file
71
app/pages/concerts/agenda.vue
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<PageSection tone="dark" content-size="default">
|
||||||
|
<SectionTitle tone="invert" pad="md">
|
||||||
|
LES CONCERTS À VENIR
|
||||||
|
</SectionTitle>
|
||||||
|
</PageSection>
|
||||||
|
<PageSection padded_size="md" content-size="default" class="">
|
||||||
|
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
|
||||||
|
<ConcertCard
|
||||||
|
v-for="c in concerts"
|
||||||
|
:key="c.id"
|
||||||
|
:id="c.slug_concert"
|
||||||
|
:title="c.titre_concert"
|
||||||
|
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
|
||||||
|
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
|
||||||
|
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||||
|
:adresse_lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||||
|
:description="c.resume_concert"
|
||||||
|
:imageUrl="c.image_illustration_concert?.url"
|
||||||
|
:imageAlt="c.image_illustration_concert?.alternativeText"
|
||||||
|
:href="`${c.slug_concert}`"
|
||||||
|
/>
|
||||||
|
</ConcertCardList>
|
||||||
|
</PageSection>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { onMounted } from "vue"
|
||||||
|
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||||
|
|
||||||
|
const { concerts, refresh } = useConcerts({
|
||||||
|
locale: "fr-FR",
|
||||||
|
populate: {
|
||||||
|
saison_concert: true,
|
||||||
|
genre_concert: true,
|
||||||
|
type_audience_concert: true,
|
||||||
|
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
direction_invite_concert: { postes_artiste_invite: true },
|
||||||
|
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
artistes_invite_concert: { postes_artiste_invite: true },
|
||||||
|
image_illustration_concert: true,
|
||||||
|
images_concert: true,
|
||||||
|
videos_concert: true,
|
||||||
|
audios_concert: true,
|
||||||
|
programme_concert: true,
|
||||||
|
representation_concert: { lieu_representation: true },
|
||||||
|
liens_youtube_concert: true,
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
saison_concert: {
|
||||||
|
nom_saison: {
|
||||||
|
$eq: "2025/2026",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
upcomingOnly: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!concerts.value?.length) {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div v-if="toto">
|
|
||||||
<h1>#{{route.params.id }} / {{ toto.title }}</h1>
|
|
||||||
<p>{{ toto.body }}</p>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<p>Chargement...</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
const route = useRoute()
|
|
||||||
const {data: toto} = await useFetch(() => 'https://jsonplaceholder.typicode.com/posts/' + route.params.id, { lazy: true })
|
|
||||||
useSeoMeta({
|
|
||||||
title: () => toto.value?.title
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
</style>
|
|
||||||
4
app/pages/concerts/index.vue
Normal file
4
app/pages/concerts/index.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup>
|
||||||
|
await navigateTo('/concerts/agenda', { redirectCode: 301 })
|
||||||
|
</script>
|
||||||
|
|
||||||
13
app/pages/concerts/jeune-public.vue
Normal file
13
app/pages/concerts/jeune-public.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/concerts/live.vue
Normal file
13
app/pages/concerts/live.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/concerts/mag.vue
Normal file
13
app/pages/concerts/mag.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/concerts/mode-emploi.vue
Normal file
13
app/pages/concerts/mode-emploi.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
71
app/pages/concerts/saison.vue
Normal file
71
app/pages/concerts/saison.vue
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<PageSection tone="dark" content-size="default">
|
||||||
|
<SectionTitle tone="invert" pad="md">
|
||||||
|
SAISON 2025/2026
|
||||||
|
</SectionTitle>
|
||||||
|
</PageSection>
|
||||||
|
<PageSection padded_size="md" content-size="default" class="">
|
||||||
|
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
|
||||||
|
<ConcertCard
|
||||||
|
v-for="c in concerts"
|
||||||
|
:key="c.id"
|
||||||
|
:id="c.slug_concert"
|
||||||
|
:title="c.titre_concert"
|
||||||
|
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
|
||||||
|
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
|
||||||
|
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||||
|
:adresse_lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||||
|
:description="c.resume_concert"
|
||||||
|
:imageUrl="c.image_illustration_concert?.url"
|
||||||
|
:imageAlt="c.image_illustration_concert?.alternativeText"
|
||||||
|
:href="`${c.slug_concert}`"
|
||||||
|
/>
|
||||||
|
</ConcertCardList>
|
||||||
|
</PageSection>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { onMounted } from "vue"
|
||||||
|
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||||
|
|
||||||
|
const { concerts, refresh } = useConcerts({
|
||||||
|
locale: "fr-FR",
|
||||||
|
populate: {
|
||||||
|
saison_concert: true,
|
||||||
|
genre_concert: true,
|
||||||
|
type_audience_concert: true,
|
||||||
|
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
direction_invite_concert: { postes_artiste_invite: true },
|
||||||
|
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||||
|
artistes_invite_concert: { postes_artiste_invite: true },
|
||||||
|
image_illustration_concert: true,
|
||||||
|
images_concert: true,
|
||||||
|
videos_concert: true,
|
||||||
|
audios_concert: true,
|
||||||
|
programme_concert: true,
|
||||||
|
representation_concert: { lieu_representation: true },
|
||||||
|
liens_youtube_concert: true,
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
saison_concert: {
|
||||||
|
nom_saison: {
|
||||||
|
$eq: "2025/2026",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
upcomingOnly: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!concerts.value?.length) {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<ConcertCard
|
<ConcertCard
|
||||||
id="1"
|
id="1"
|
||||||
title="TITRE DU CONCERT EN MAJUSCULE"
|
title="TITRE DU CONCERT EN MAJUSCULE"
|
||||||
venue="Nom du lieu, éventuellement de la salle"
|
lieu="Nom du lieu, éventuellement de la salle"
|
||||||
dateISO="2026-01-15T20:30:00+01:00"
|
dateISO="2026-01-15T20:30:00+01:00"
|
||||||
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
||||||
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<ConcertCard
|
<ConcertCard
|
||||||
id="1"
|
id="1"
|
||||||
title="TITRE DU CONCERT EN MAJUSCULE"
|
title="TITRE DU CONCERT EN MAJUSCULE"
|
||||||
venue="Nom du lieu, éventuellement de la salle"
|
lieu="Nom du lieu, éventuellement de la salle"
|
||||||
dateISO="2026-01-15T20:30:00+01:00"
|
dateISO="2026-01-15T20:30:00+01:00"
|
||||||
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
||||||
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
||||||
@@ -39,10 +39,8 @@
|
|||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
|
|
||||||
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
||||||
console.log("STRAPI_URL : ",STRAPI_URL)
|
|
||||||
|
|
||||||
|
|
||||||
// Config app (pour ton SEO)
|
// Config app
|
||||||
const config = useAppConfig()
|
const config = useAppConfig()
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: config.title
|
title: config.title
|
||||||
@@ -78,10 +76,6 @@
|
|||||||
|
|
||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
console.log("test 3 : ",appConfig.title) // "Mon site Nuxt"
|
console.log("test 3 : ",appConfig.title) // "Mon site Nuxt"
|
||||||
onMounted(() => {
|
|
||||||
clientLog('info', 'test de log depuis vuejs', { })
|
|
||||||
clientLog('info', `STRAPI_URL : ${STRAPI_URL}`, { strapiUrl: STRAPI_URL })
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
<!-- ================== -->
|
<!-- ================== -->
|
||||||
<!-- Fond noir -->
|
<!-- Fond noir -->
|
||||||
@@ -15,40 +16,17 @@
|
|||||||
<PageSection padded_size="md" content-size="default" class="remonter_concert_list">
|
<PageSection padded_size="md" content-size="default" class="remonter_concert_list">
|
||||||
<ConcertCardList>
|
<ConcertCardList>
|
||||||
<ConcertCard
|
<ConcertCard
|
||||||
id="1"
|
v-for="c in concerts"
|
||||||
title="TITRE DU CONCERT EN MAJUSCULE"
|
:key="c.id"
|
||||||
venue="Nom du lieu, éventuellement de la salle"
|
:id="c.slug_concert"
|
||||||
dateISO="2026-01-15T20:30:00+01:00"
|
:title="c.titre_concert"
|
||||||
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||||
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
|
||||||
imageUrl="https://picsum.photos/id/56/500/700"
|
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
|
||||||
imageAlt="Orchestre sur scène"
|
:description="c.resume_concert"
|
||||||
ctaHref="/concert[id]"
|
:imageUrl="c.image_illustration_concert?.url"
|
||||||
detailsHref="/concerts/concert_template"
|
:imageAlt="c.image_illustration_concert?.alternativeText"
|
||||||
/>
|
:href="`/concerts/${c.slug_concert}`"
|
||||||
<ConcertCard
|
|
||||||
id="1"
|
|
||||||
title="TITRE DU CONCERT EN MAJUSCULE"
|
|
||||||
venue="Nom du lieu, éventuellement de la salle"
|
|
||||||
dateISO="2026-01-15T20:30:00+01:00"
|
|
||||||
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
|
||||||
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
|
||||||
imageUrl="https://picsum.photos/id/56/500/700"
|
|
||||||
imageAlt="Orchestre sur scène"
|
|
||||||
ctaHref="/concert[id]"
|
|
||||||
detailsHref="/concerts/concert_template"
|
|
||||||
/>
|
|
||||||
<ConcertCard
|
|
||||||
id="1"
|
|
||||||
title="TITRE DU CONCERT EN MAJUSCULE"
|
|
||||||
venue="Nom du lieu, éventuellement de la salle"
|
|
||||||
dateISO="2026-01-15T20:30:00+01:00"
|
|
||||||
dateLabel="Jeudi 15 janvier 2026 — 20h30"
|
|
||||||
description="Description du concert assez courte qui reprend l'essentiel, les artistes... On pourra écrire un nombre de lettres limitées."
|
|
||||||
imageUrl="https://picsum.photos/id/56/500/700"
|
|
||||||
imageAlt="Orchestre sur scène"
|
|
||||||
ctaHref="/concert[id]"
|
|
||||||
detailsHref="/concerts/concert_template"
|
|
||||||
/>
|
/>
|
||||||
</ConcertCardList>
|
</ConcertCardList>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
@@ -65,7 +43,7 @@
|
|||||||
</SectionTitle>
|
</SectionTitle>
|
||||||
<SectionContent pad="xs" class="theme_ppt--description">
|
<SectionContent pad="xs" class="theme_ppt--description">
|
||||||
<DsText tone="invert" size="lg" class="theme_ppt--txt" >
|
<DsText tone="invert" size="lg" class="theme_ppt--txt" >
|
||||||
Ici le texte qui décrit le concept de Tous à l’Orchestre - Dans les régions - Ici le texte qui décrit le concept de Tous à l’Orchestre - Dans les régions - Ici le texte qui décrit le concept de Tous à l’Orchestre - Dans les régions -
|
Les 95 musiciennes et musiciens proposent chaque saison plus de 120 concerts dans des salles et théâtres, des lieux culturels et des espaces atypiques de la région francilienne. Porté par une forte mission territoriale, l’orchestre s’engage à rendre la musique symphonique accessible à toutes et tous, en la faisant vivre au plus près des habitants grâce notamment à des actions culturelles, pédagogiques et participatives au cœur du territoire.
|
||||||
</DsText>
|
</DsText>
|
||||||
<DsButtonArrow to="/" variant="invert">
|
<DsButtonArrow to="/" variant="invert">
|
||||||
Carte des événements
|
Carte des événements
|
||||||
@@ -161,12 +139,14 @@
|
|||||||
<BannierePros />
|
<BannierePros />
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, computed } from 'vue'
|
import { onMounted, computed } from 'vue'
|
||||||
import { clientLog } from '~/utils/clientLog'
|
import { clientLog } from '~/utils/clientLog'
|
||||||
|
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||||
import SectionContent from '../components/section/SectionContent.vue'
|
import SectionContent from '../components/section/SectionContent.vue'
|
||||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||||
@@ -181,7 +161,6 @@
|
|||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
|
|
||||||
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
||||||
console.log("STRAPI_URL : ",STRAPI_URL)
|
|
||||||
|
|
||||||
// Config app (pour SEO)
|
// Config app (pour SEO)
|
||||||
const config = useAppConfig()
|
const config = useAppConfig()
|
||||||
@@ -189,38 +168,34 @@
|
|||||||
title: config.title
|
title: config.title
|
||||||
})
|
})
|
||||||
|
|
||||||
// On récupère le fichier le plus récent de la Media Library Strapi
|
const appConfig = useAppConfig()
|
||||||
const { data, error } = await useFetch(
|
console.log("Bienvenue : ",appConfig.title)
|
||||||
() => `${STRAPI_URL}/api/upload/files?pagination[pageSize]=1&sort=createdAt:desc`
|
|
||||||
)
|
|
||||||
|
|
||||||
const imageUrl = computed(() => {
|
//--------------------
|
||||||
const file = data.value?.[0]
|
// DONNÉES POUR LES CONCERTS À VENIR …
|
||||||
console.log("file : ",file)
|
//--------------------
|
||||||
if (!file) return null
|
const { concerts, refresh } = useConcerts({
|
||||||
|
locale: "fr-FR",
|
||||||
// Si Strapi renvoie une URL absolue (S3/OVH)
|
populate: {
|
||||||
if (file.url?.startsWith('http')) {
|
saison_concert: true,
|
||||||
return file.url
|
image_illustration_concert: true,
|
||||||
}
|
representation_concert: { lieu_representation: true },
|
||||||
|
},
|
||||||
// Si jamais c'était une URL relative
|
filters: {
|
||||||
return `${STRAPI_URL}${file.url}`
|
saison_concert: {
|
||||||
|
nom_saison: {
|
||||||
|
$eq: "2025/2026",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
upcomingOnly: true,
|
||||||
|
limit: 3,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (error.value) {
|
|
||||||
console.error('Erreur en récupérant les fichiers Strapi :', error.value)
|
|
||||||
clientLog('error', 'Erreur en récupérant les fichiers Strapi', {
|
|
||||||
endpoint: `${STRAPI_URL}/api/upload/files?pagination[pageSize]=1&sort=createdAt:desc`,
|
|
||||||
error: error.value?.message || error.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const appConfig = useAppConfig()
|
|
||||||
console.log("test 3 : ",appConfig.title) // "Mon site Nuxt"
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
clientLog('info', 'test de log depuis vuejs', { })
|
if (!concerts.value?.length) {
|
||||||
clientLog('info', `STRAPI_URL : ${STRAPI_URL}`, { strapiUrl: STRAPI_URL })
|
refresh()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
|
|||||||
13
app/pages/mecenat/entreprises.vue
Normal file
13
app/pages/mecenat/entreprises.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
4
app/pages/mecenat/index.vue
Normal file
4
app/pages/mecenat/index.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup>
|
||||||
|
await navigateTo('/mecenat/soutenir', { redirectCode: 301 })
|
||||||
|
</script>
|
||||||
|
|
||||||
13
app/pages/mecenat/mecenes.vue
Normal file
13
app/pages/mecenat/mecenes.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mecenat/particuliers.vue
Normal file
13
app/pages/mecenat/particuliers.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mecenat/projets.vue
Normal file
13
app/pages/mecenat/projets.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mecenat/soutenir.vue
Normal file
13
app/pages/mecenat/soutenir.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mediation/amateurs.vue
Normal file
13
app/pages/mediation/amateurs.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
4
app/pages/mediation/index.vue
Normal file
4
app/pages/mediation/index.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup>
|
||||||
|
await navigateTo('/mediation/petite-enfance', { redirectCode: 301 })
|
||||||
|
</script>
|
||||||
|
|
||||||
13
app/pages/mediation/insertion-pro.vue
Normal file
13
app/pages/mediation/insertion-pro.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mediation/petite-enfance.vue
Normal file
13
app/pages/mediation/petite-enfance.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mediation/ressources-pedagogiques.vue
Normal file
13
app/pages/mediation/ressources-pedagogiques.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mediation/scolaires.vue
Normal file
13
app/pages/mediation/scolaires.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/mediation/social.vue
Normal file
13
app/pages/mediation/social.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/artistes-invitees.vue
Normal file
13
app/pages/orchestre/artistes-invitees.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/direction.vue
Normal file
13
app/pages/orchestre/direction.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Page en construction direction
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/discographie.vue
Normal file
13
app/pages/orchestre/discographie.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
4
app/pages/orchestre/index.vue
Normal file
4
app/pages/orchestre/index.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup>
|
||||||
|
await navigateTo('/orchestre/missions', { redirectCode: 301 })
|
||||||
|
</script>
|
||||||
|
|
||||||
13
app/pages/orchestre/missions.vue
Normal file
13
app/pages/orchestre/missions.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Page en construction Missions
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/musiciens.vue
Normal file
13
app/pages/orchestre/musiciens.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/partenaires.vue
Normal file
13
app/pages/orchestre/partenaires.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/orchestre/soutenir.vue
Normal file
13
app/pages/orchestre/soutenir.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
//const STRAPI_URL = "http://localhost:1337"
|
//const STRAPI_URL = "http://localhost:1337"
|
||||||
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
const STRAPI_URL = runtimeConfig.public.strapiUrl
|
||||||
console.log("STRAPI_URL : ",STRAPI_URL)
|
|
||||||
|
|
||||||
// Config app (pour SEO)
|
// Config app (pour SEO)
|
||||||
const config = useAppConfig()
|
const config = useAppConfig()
|
||||||
@@ -51,11 +50,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
console.log("test 3 : ",appConfig.title) // "Mon site Nuxt"
|
console.log("Bienvenue : ",appConfig.title)
|
||||||
onMounted(() => {
|
|
||||||
clientLog('info', 'test de log depuis vuejs', { })
|
|
||||||
clientLog('info', `STRAPI_URL : ${STRAPI_URL}`, { strapiUrl: STRAPI_URL })
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
13
app/pages/professionnels/candidats.vue
Normal file
13
app/pages/professionnels/candidats.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
4
app/pages/professionnels/index.vue
Normal file
4
app/pages/professionnels/index.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup>
|
||||||
|
await navigateTo('/professionnels/programmer-orchestre', { redirectCode: 301 })
|
||||||
|
</script>
|
||||||
|
|
||||||
13
app/pages/professionnels/louer.vue
Normal file
13
app/pages/professionnels/louer.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/professionnels/presse.vue
Normal file
13
app/pages/professionnels/presse.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/professionnels/programmer-orchestre.vue
Normal file
13
app/pages/professionnels/programmer-orchestre.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/professionnels/recrutement.vue
Normal file
13
app/pages/professionnels/recrutement.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
13
app/pages/professionnels/studio.vue
Normal file
13
app/pages/professionnels/studio.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
title: config.title
|
title: config.title
|
||||||
})
|
})
|
||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
console.log("test 3 : ",appConfig.title) // "Mon site Nuxt"
|
console.log("test 3 : ",appConfig.title)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
16
app/utils/dateFormat.js
Normal file
16
app/utils/dateFormat.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export function formatDateLong(iso) {
|
||||||
|
if (!iso) return ""
|
||||||
|
const d = new Date(iso)
|
||||||
|
const date = new Intl.DateTimeFormat("fr-FR", {
|
||||||
|
weekday: "long",
|
||||||
|
day: "numeric",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
}).format(d)
|
||||||
|
const time = new Intl.DateTimeFormat("fr-FR", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
hour12: false,
|
||||||
|
}).format(d).replace(":", "h")
|
||||||
|
return `${date} — ${time}`
|
||||||
|
}
|
||||||
33
app/utils/strapi.js
Normal file
33
app/utils/strapi.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// app/utils/strapi.js
|
||||||
|
|
||||||
|
export function getStrapiBaseUrl(event) {
|
||||||
|
// En server/Nitro, on récupère runtimeConfig via l'event si dispo,
|
||||||
|
// sinon on retombe sur la variable d'env publique.
|
||||||
|
const base =
|
||||||
|
event?.context?.runtimeConfig?.public?.strapiUrl ||
|
||||||
|
process.env.NUXT_PUBLIC_STRAPI_URL
|
||||||
|
|
||||||
|
if (!base) {
|
||||||
|
throw new Error("Missing runtimeConfig.public.strapiUrl (NUXT_PUBLIC_STRAPI_URL)")
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new URL(base)
|
||||||
|
} catch {
|
||||||
|
throw new Error(`Invalid Strapi base URL: ${base}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.replace(/\/$/, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function strapiFetch(event, path, options = {}) {
|
||||||
|
const base = getStrapiBaseUrl(event)
|
||||||
|
const url = `${base}${path.startsWith("/") ? path : `/${path}`}`
|
||||||
|
|
||||||
|
return await $fetch(url, {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...(options.headers || {}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
`ds-heading--${resolvedsize}`,
|
`ds-heading--${resolvedsize}`,
|
||||||
`ds-heading--${resolvedWeight}`,
|
`ds-heading--${resolvedWeight}`,
|
||||||
`ds-heading--${resolvedspacing}`, //margin-bottom
|
`ds-heading--${resolvedspacing}`, //margin-bottom
|
||||||
`ds-heading--${tone}`
|
`ds-heading--${tone}`,
|
||||||
|
`ds-heading--${textcase}`
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
as: { type: String, default: 'h2' }, // h1/h2/h3/p/span...
|
as: { type: String, default: 'h2' }, // h1/h2/h3/p/span...
|
||||||
font: { type: String, default: 'roboto' }, // barlow | brandon
|
font: { type: String, default: 'roboto' }, // barlow | brandon
|
||||||
tone: { type: String, default: 'default' }, // default/muted/invert
|
tone: { type: String, default: 'default' }, // default/muted/invert
|
||||||
|
textcase: { type: String, default: 'default' }, // uppercase
|
||||||
})
|
})
|
||||||
|
|
||||||
const resolvedWeight = computed(() => {
|
const resolvedWeight = computed(() => {
|
||||||
@@ -133,7 +135,8 @@
|
|||||||
&--bleu_fonce { color: var(--c-bleu_fonce); }
|
&--bleu_fonce { color: var(--c-bleu_fonce); }
|
||||||
&--bleu_clair { color: var(--c-bleu_clair); }
|
&--bleu_clair { color: var(--c-bleu_clair); }
|
||||||
|
|
||||||
|
// CASE
|
||||||
|
&--uppercase {text-transform: uppercase;}
|
||||||
|
|
||||||
&--info { color: var(--c-info); }
|
&--info { color: var(--c-info); }
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
&--16-9 { aspect-ratio: 16 / 9; }
|
&--16-9 { aspect-ratio: 16 / 9; }
|
||||||
&--4-3 { aspect-ratio: 4 / 3; }
|
&--4-3 { aspect-ratio: 4 / 3; }
|
||||||
|
&--3-4 { aspect-ratio: 3 / 4; }
|
||||||
&--square { aspect-ratio: 1 / 1; }
|
&--square { aspect-ratio: 1 / 1; }
|
||||||
|
|
||||||
.ds-media__img {
|
.ds-media__img {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
&--space-20 { margin-bottom: var(--sp-20); }
|
&--space-20 { margin-bottom: var(--sp-20); }
|
||||||
&--space-16 { margin-bottom: var(--sp-16); }
|
&--space-16 { margin-bottom: var(--sp-16); }
|
||||||
&--space-6 { margin-bottom: var(--sp-6); }
|
&--space-6 { margin-bottom: var(--sp-6); }
|
||||||
|
&--space-0 { margin-bottom: 0px; }
|
||||||
|
|
||||||
&--default { color: var(--c-text, #111); }
|
&--default { color: var(--c-text, #111); }
|
||||||
&--muted { color: var(--c-text-muted, #555); }
|
&--muted { color: var(--c-text-muted, #555); }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
--c-surface: #ffffff;
|
--c-surface: #ffffff;
|
||||||
--c-text-muted: #555;
|
--c-text-muted: #555;
|
||||||
--c-text-invert: #fff;
|
--c-text-invert: #fff;
|
||||||
|
--c-text-black-soft: #595959;
|
||||||
|
|
||||||
/* Marque / accent (ex: rouge ONDIF) */
|
/* Marque / accent (ex: rouge ONDIF) */
|
||||||
//--c-brand_rouge: #E30613;
|
//--c-brand_rouge: #E30613;
|
||||||
|
|||||||
@@ -69,8 +69,14 @@
|
|||||||
--title-lg2: var(--fs-30);
|
--title-lg2: var(--fs-30);
|
||||||
--title-xl: var(--fs-32);
|
--title-xl: var(--fs-32);
|
||||||
--title-2xl: var(--fs-40);
|
--title-2xl: var(--fs-40);
|
||||||
|
|
||||||
|
/* ICONES PUCE LISTE */
|
||||||
|
--strapi-li-icon: url('/icons/list-bullet.svg');
|
||||||
|
--strapi-li-icon-nested: url('/icons/list-bullet-nested.svg');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Option : ajustements desktop */
|
/* Option : ajustements desktop */
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ export default defineNuxtConfig({
|
|||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
// Server-side only (jamais exposé au client)
|
// Server-side only (jamais exposé au client)
|
||||||
strapiToken: process.env.STRAPI_API_TOKEN || '',
|
strapiToken: process.env.STRAPI_API_TOKEN || '',
|
||||||
instagramAppId: process.env.NUXT_INSTAGRAM_APP_ID,
|
//instagramAppId: process.env.NUXT_INSTAGRAM_APP_ID,
|
||||||
instagramClientToken: process.env.NUXT_INSTAGRAM_CLIENT_TOKEN,
|
//instagramClientToken: process.env.NUXT_INSTAGRAM_CLIENT_TOKEN,
|
||||||
|
|
||||||
// 🌍 Public (accessible dans le navigateur)
|
// 🌍 Public (accessible dans le navigateur)
|
||||||
public: {
|
public: {
|
||||||
|
|||||||
11
public/img/icones/angle-right-grey.svg
Normal file
11
public/img/icones/angle-right-grey.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="225px" height="386px" viewBox="0 0 225 386" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>Path</title>
|
||||||
|
<g id="Flèche" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="500" transform="translate(-234, -31)" fill="#6D798A" fill-rule="nonzero">
|
||||||
|
<g id="angle-right" transform="translate(10, -96)">
|
||||||
|
<path d="M439.1,297.4 C451.6,309.9 451.6,330.2 439.1,342.7 L279.1,502.7 C266.6,515.2 246.3,515.2 233.8,502.7 C221.3,490.2 221.3,469.9 233.8,457.4 L371.2,320 L233.9,182.6 C221.4,170.1 221.4,149.8 233.9,137.3 C246.4,124.8 266.7,124.8 279.2,137.3 L439.2,297.3 L439.1,297.4 Z" id="Path"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 801 B |
1
public/img/icones/angle-right.svg
Normal file
1
public/img/icones/angle-right.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M439.1 297.4C451.6 309.9 451.6 330.2 439.1 342.7L279.1 502.7C266.6 515.2 246.3 515.2 233.8 502.7C221.3 490.2 221.3 469.9 233.8 457.4L371.2 320L233.9 182.6C221.4 170.1 221.4 149.8 233.9 137.3C246.4 124.8 266.7 124.8 279.2 137.3L439.2 297.3z"/></svg>
|
||||||
|
After Width: | Height: | Size: 470 B |
9
public/img/icones/house-grey.svg
Normal file
9
public/img/icones/house-grey.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="512px" height="466px" viewBox="0 0 512 466" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>Shape</title>
|
||||||
|
<g id="Flèche" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="house" transform="translate(-64, -64)" fill="#6D798A" fill-rule="nonzero">
|
||||||
|
<path d="M341.8,72.6 C329.5,61.2 310.5,61.2 298.3,72.6 L74.3,280.6 C64.7,289.6 61.5,303.5 66.3,315.7 C71.1,327.9 82.8,336 96,336 L112,336 L112,499.041234 C112,534.341234 146.941152,529.030576 182.241152,529.030576 L462.664813,529.030576 C497.964813,529.030576 528,534.341234 528,499.041234 L528,336 L544,336 C557.2,336 569,327.9 573.8,315.7 C578.6,303.5 575.4,289.5 565.8,280.6 L341.8,72.6 Z M304,384 L336,384 C362.5,384 384,405.5 384,432 L384,528 L256,528 L256,432 C256,405.5 277.5,384 304,384 Z" id="Shape"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 944 B |
1
public/img/icones/house.svg
Normal file
1
public/img/icones/house.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M341.8 72.6C329.5 61.2 310.5 61.2 298.3 72.6L74.3 280.6C64.7 289.6 61.5 303.5 66.3 315.7C71.1 327.9 82.8 336 96 336L112 336L112 512C112 547.3 140.7 576 176 576L464 576C499.3 576 528 547.3 528 512L528 336L544 336C557.2 336 569 327.9 573.8 315.7C578.6 303.5 575.4 289.5 565.8 280.6L341.8 72.6zM304 384L336 384C362.5 384 384 405.5 384 432L384 528L256 528L256 432C256 405.5 277.5 384 304 384z"/></svg>
|
||||||
|
After Width: | Height: | Size: 619 B |
9
server/api/__strapi__/concerts.get.js
Normal file
9
server/api/__strapi__/concerts.get.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// server/api/__strapi__/concerts.get.js
|
||||||
|
|
||||||
|
import { createStrapiProxyHandler } from "~~/server/utils/strapiEndpoint"
|
||||||
|
|
||||||
|
export default defineEventHandler(
|
||||||
|
createStrapiProxyHandler({
|
||||||
|
strapiPath: "/api/concerts",
|
||||||
|
})
|
||||||
|
)
|
||||||
33
server/utils/strapiEndpoint.js
Normal file
33
server/utils/strapiEndpoint.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { createError, getQuery } from "h3"
|
||||||
|
import { strapiFetch } from "@/utils/strapi.js"
|
||||||
|
import logger from "~~/server/utils/logger"
|
||||||
|
|
||||||
|
export function createStrapiProxyHandler({ strapiPath }) {
|
||||||
|
return async (event) => {
|
||||||
|
try {
|
||||||
|
const query = getQuery(event)
|
||||||
|
const qs = new URLSearchParams(query).toString()
|
||||||
|
const path = qs ? `${strapiPath}?${qs}` : strapiPath
|
||||||
|
|
||||||
|
return await strapiFetch(event, path)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("Strapi request failed", {
|
||||||
|
label: "back-end",
|
||||||
|
statusCode: err?.statusCode,
|
||||||
|
statusMessage: err?.statusMessage,
|
||||||
|
message: err?.message,
|
||||||
|
data: err?.data,
|
||||||
|
url: event?.path,
|
||||||
|
method: event?.method,
|
||||||
|
})
|
||||||
|
|
||||||
|
throw createError({
|
||||||
|
statusCode: err?.statusCode || 502,
|
||||||
|
statusMessage:
|
||||||
|
err?.statusMessage ||
|
||||||
|
err?.message ||
|
||||||
|
"Strapi request failed",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user