Compare commits
51 Commits
8962aad738
...
main
Author | SHA1 | Date | |
---|---|---|---|
859924d6be | |||
a26ec95983 | |||
575cc28717 | |||
e5665a24e7 | |||
6e42e8c800 | |||
bb7d5f16e1 | |||
1e30a79f73 | |||
455545482f | |||
2de488f3bf | |||
370949cfe0 | |||
6ff6c5229d | |||
61bc2541f7 | |||
1f67ee9810 | |||
ccd83369fd | |||
7de52a3b45 | |||
398d0f6957 | |||
c0a0fda9c2 | |||
41135bb2c7 | |||
2ea897e563 | |||
6ca8c1bdcf | |||
7555056b5b | |||
35e970a160 | |||
13c863d09b | |||
d7922166ba | |||
d2f5d7d840 | |||
2bcddaabcf | |||
79a0ab2a1a | |||
d6c1992e11 | |||
7a61fc4907 | |||
2960b936b1 | |||
483a0f14ec | |||
7cce542804 | |||
f26a7b0c21 | |||
fd4bc23930 | |||
ac6ff78934 | |||
f32f4a019d | |||
c7c1e0c0ed | |||
077c36d3be | |||
4c3d796b17 | |||
c85fdc8d27 | |||
5b52cee3fe | |||
e4de9aa3e5 | |||
f8958416fc | |||
da9fd594a4 | |||
4d9445d3c5 | |||
0d13783421 | |||
ce5b3ec3ab | |||
bd1e7c4030 | |||
3e0225f84e | |||
9d3e144748 | |||
58a6da1d94 |
190
.drone.yml
190
.drone.yml
@ -34,6 +34,42 @@ kind: secret
|
||||
name: PRODUCTION_AWS_SECRET_ACCESS_KEY
|
||||
data: JX44CwSuvFmYhJCW+vxC4GmUKbO83VyYeImCvIgtkdeC1cRtNEgCA6gWoclT4vSBrk6AW6iQnh3MSpIhOERSn/prcWiTwbBn6YqdUaQ18B9/Dp3Qk1RtOkS2wKI=
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_ACCESS_KEY_ID
|
||||
kind: secret
|
||||
name: TEST_AWS_ACCESS_KEY_ID
|
||||
data: Bf6VZlmdGQGAOQtwtiOzRCqhnFaW310rw9LqMFVoaQBHiCbso23Zrt6G1N3J0nYGI/oLMhM3
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_SECRET_ACCESS_KEY
|
||||
kind: secret
|
||||
name: TEST_AWS_SECRET_ACCESS_KEY
|
||||
data: kIq0RuZPg2gSamnbei121OHNtupioEYyVay8CnNxNz+u0fEh0c1qnAKM506h+XbwMr+HDyQEUNDM09fqzM14xmRxz8EZtqg6hXVPUcfEIG9nXI9VtnCKMwoKTMQ=
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_ACCESS_KEY_ID
|
||||
kind: secret
|
||||
name: DMH_AWS_ACCESS_KEY_ID
|
||||
data: ZJi1IozPCoLgmwBnQy9OkOe7ByerC/b94aTNivtkAYh1K9A4WR+eXGNrbyXZci06HYjV8pBU
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_SECRET_ACCESS_KEY
|
||||
kind: secret
|
||||
name: DMH_AWS_SECRET_ACCESS_KEY
|
||||
data: sLiY4plTjS73Dzw0qHaAuSR4PiHGIhb6H2i1KyP2GpjvIDyaxbR2gjsjzn3E8e0gAtCiIM10nbvvAMvGmPoh1dLuYlmHj2YdOQA8wbjkA9jSqe9owbfxfrcEuDA=
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_ACCESS_KEY_ID
|
||||
kind: secret
|
||||
name: FOURCHE_AWS_ACCESS_KEY_ID
|
||||
data: GgpM5vSzE4N4ldcs+Db+sjG/siXmO+sYvw9DJYr0puAIv3jejlzwa3zJGcwGb2fmwCqyxied
|
||||
|
||||
---
|
||||
# drone encrypt Weko/ceiba-scores $AWS_SECRET_ACCESS_KEY
|
||||
kind: secret
|
||||
name: FOURCHE_AWS_SECRET_ACCESS_KEY
|
||||
data: rEE5ttbao6dla92YOw1vh1VE1sBWAjen+jfP/ZdUSDnFlkZKY56ms+V0jOReGulhwbVRxQijp1fTS43TW/vJbq3XSeTVUwDGTHLZFQ+yGObvr+4DKOVIRqp/rJE=
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@ -41,15 +77,17 @@ name: prod
|
||||
|
||||
steps:
|
||||
- name: install npm
|
||||
image: node:current-alpine
|
||||
image: node:20.12.2-alpine
|
||||
volumes:
|
||||
- name: node_modules
|
||||
path: /drone/src/node_modules
|
||||
commands:
|
||||
- npm i
|
||||
- npm i --include dev
|
||||
- npm run fetchData
|
||||
- npm run lint
|
||||
#- npm run lint
|
||||
- npm run build
|
||||
environment:
|
||||
NODE_ENV: 'production'
|
||||
|
||||
- name: deploy on s3
|
||||
image: minio/mc
|
||||
@ -85,15 +123,17 @@ name: staging
|
||||
|
||||
steps:
|
||||
- name: install npm
|
||||
image: node:current-alpine
|
||||
image: node:20.12.2-alpine
|
||||
volumes:
|
||||
- name: node_modules
|
||||
path: /drone/src/node_modules
|
||||
commands:
|
||||
- npm i
|
||||
- npm run fetchData
|
||||
- npm run lint
|
||||
#- npm run lint
|
||||
- npm run build
|
||||
environment:
|
||||
NODE_ENV: 'staging'
|
||||
|
||||
- name: deploy on s3
|
||||
image: minio/mc
|
||||
@ -120,4 +160,142 @@ steps:
|
||||
volumes:
|
||||
- name: node_modules
|
||||
host:
|
||||
path: /tmp/drone/cache/weko/scores.ceiba-conseil.com/node_modules
|
||||
path: /tmp/drone/cache/weko/staging.scores.ceiba-conseil.com/node_modules
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: test
|
||||
|
||||
steps:
|
||||
- name: install npm
|
||||
image: node:20.12.2-alpine
|
||||
volumes:
|
||||
- name: node_modules
|
||||
path: /drone/src/node_modules
|
||||
commands:
|
||||
- npm i
|
||||
- npm run fetchData
|
||||
#- npm run lint
|
||||
- npm run build
|
||||
environment:
|
||||
NODE_ENV: 'test'
|
||||
|
||||
- name: deploy on s3
|
||||
image: minio/mc
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: TEST_AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: TEST_AWS_SECRET_ACCESS_KEY
|
||||
commands:
|
||||
- mc alias set garage https://s3.garage.resilien.cloud $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY --api S3v4
|
||||
- mc mirror --overwrite /drone/src/dist garage/test.scores.ceiba-conseil.com
|
||||
|
||||
- name: notify
|
||||
image: plugins/matrix@sha256:f1affb31b0c86963c97c6f976fa0dcb3cc84272057fd8558d609d28b3064bd7f
|
||||
settings:
|
||||
homeserver: https://converser.eu
|
||||
roomid: "QwOITmkKxRJJyCSDOZ:converser.eu"
|
||||
userid: "resilien:converser.eu"
|
||||
accesstoken:
|
||||
from_secret: MATRIX_ACCESSTOKEN
|
||||
when:
|
||||
status: [ failure ]
|
||||
|
||||
volumes:
|
||||
- name: node_modules
|
||||
host:
|
||||
path: /tmp/drone/cache/weko/test.scores.ceiba-conseil.com/node_modules
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: DMH
|
||||
|
||||
steps:
|
||||
- name: install npm
|
||||
image: node:20.12.2-alpine
|
||||
volumes:
|
||||
- name: node_modules
|
||||
path: /drone/src/node_modules
|
||||
commands:
|
||||
- npm i
|
||||
- npm run fetchData
|
||||
#- npm run lint
|
||||
- apk add --no-cache jq
|
||||
- echo $(cat src/data.json | jq -c '[.[4]]') > src/data.json
|
||||
- npm run build
|
||||
|
||||
- name: deploy on s3
|
||||
image: minio/mc
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: DMH_AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: DMH_AWS_SECRET_ACCESS_KEY
|
||||
commands:
|
||||
- mc alias set garage https://s3.garage.resilien.cloud $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY --api S3v4
|
||||
- mc mirror --overwrite /drone/src/dist garage/dmh.ceiba-conseil.com
|
||||
|
||||
- name: notify
|
||||
image: plugins/matrix@sha256:f1affb31b0c86963c97c6f976fa0dcb3cc84272057fd8558d609d28b3064bd7f
|
||||
settings:
|
||||
homeserver: https://converser.eu
|
||||
roomid: "QwOITmkKxRJJyCSDOZ:converser.eu"
|
||||
userid: "resilien:converser.eu"
|
||||
accesstoken:
|
||||
from_secret: MATRIX_ACCESSTOKEN
|
||||
when:
|
||||
status: [ failure ]
|
||||
|
||||
volumes:
|
||||
- name: node_modules
|
||||
host:
|
||||
path: /tmp/drone/cache/weko/dmh.ceiba-conseil.com/node_modules
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: FOURCHE
|
||||
|
||||
steps:
|
||||
- name: install npm
|
||||
image: node:20.12.2-alpine
|
||||
volumes:
|
||||
- name: node_modules
|
||||
path: /drone/src/node_modules
|
||||
commands:
|
||||
- npm i
|
||||
- npm run fetchData
|
||||
#- npm run lint
|
||||
- apk add --no-cache jq
|
||||
- echo $(jq '[.[] | select(.id == 7 or .id == 11)]' src/data.json) > src/data.json
|
||||
- npm run build
|
||||
|
||||
- name: deploy on s3
|
||||
image: minio/mc
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: FOURCHE_AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: FOURCHE_AWS_SECRET_ACCESS_KEY
|
||||
commands:
|
||||
- mc alias set garage https://s3.garage.resilien.cloud $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY --api S3v4
|
||||
- mc mirror --overwrite /drone/src/dist garage/fourche.ceiba-conseil.com
|
||||
|
||||
- name: notify
|
||||
image: plugins/matrix@sha256:f1affb31b0c86963c97c6f976fa0dcb3cc84272057fd8558d609d28b3064bd7f
|
||||
settings:
|
||||
homeserver: https://converser.eu
|
||||
roomid: "QwOITmkKxRJJyCSDOZ:converser.eu"
|
||||
userid: "resilien:converser.eu"
|
||||
accesstoken:
|
||||
from_secret: MATRIX_ACCESSTOKEN
|
||||
when:
|
||||
status: [ failure ]
|
||||
|
||||
volumes:
|
||||
- name: node_modules
|
||||
host:
|
||||
path: /tmp/drone/cache/weko/fourche.ceiba-conseil.com/node_modules
|
||||
|
@ -10,5 +10,6 @@ module.exports = {
|
||||
],
|
||||
env: {
|
||||
"vue/setup-compiler-macros": true,
|
||||
node: true,
|
||||
},
|
||||
};
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -28,5 +28,8 @@ coverage
|
||||
*.sw?
|
||||
|
||||
# app
|
||||
src/data.json
|
||||
src/*.json
|
||||
public/answers
|
||||
public/homepage.webp
|
||||
public/logo.png
|
||||
public/favicon/*.png
|
||||
|
47
README.md
47
README.md
@ -2,34 +2,41 @@
|
||||
|
||||
Vous trouverez ici le code source de l'application de Scores de [Ceiba Conseil](https://www.ceiba-conseil.com/).
|
||||
|
||||
## Recommended IDE Setup
|
||||
## Information
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin).
|
||||
- Le projet est développé par _[Weko](https://weko.io)_ et hébergé par _[RésiLien](https://resilien.fr)_
|
||||
- L'application utilise [un script](./scripts/fetchData.js) permettant d'importer des contenus depuis [une interface d'administration](https://admin.ceiba-conseil.com)
|
||||
- [Un outil automatique](https://ci.resilien.fr/Weko/ceiba-scores) permet une compilation automatique du projet lorsqu'un changement est effectué coté administration
|
||||
- [Les emojis](https://twemoji-cheatsheet.vercel.app/) sont libres de droit proposé par _Twitter_
|
||||
- _RésiLien_ reçoit des notifications automatiques lorsqu'un problème arrive lors de la compilation sur le canal _Matrix_ suivant https://matrix.to/#/#resilien-monitoring:converser.eu
|
||||
|
||||
## Customize configuration
|
||||
## Développement
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
L'application a été développée avec le framework Javascript _[Vue.js](https://vuejs.org/)_ et l'outil _[Vite](https://vitejs.dev/)_.
|
||||
Il utilise _[NPM](https://www.npmjs.com/)_ pour la gestion des dépendances Javascript.
|
||||
|
||||
## Project Setup
|
||||
### Recommandation pour votre environnement de développement
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
_[VSCode](https://code.visualstudio.com/)_ + _[Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)_ (et désactiver _Vetur_) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin).
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
Une configuration spécifique à _Vite_ peut être mise en place, voir [la référence](https://vitejs.dev/config/).
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
### Commandes
|
||||
|
||||
### Compile and Minify for Production
|
||||
- Installation des dépendances : `npm install`
|
||||
- Import des données de l'administration : `npm run fetchData`
|
||||
- Compilation avec du _Hot-Reload_ (Rechargement à chaud) pour le développement : `npm run dev`
|
||||
- Compilation et minification pour la production : `npm run build`
|
||||
- Les règles de mise en forme sont assurées par _[ESLint](https://eslint.org/)_ : `npm run lint`
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
## Logiciels utilisés
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
_RésiLien_ met en place des outils open source eprouvés dans le temps et dont les communautés sont assez grandes pour permettre une perenité de ses projets.
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
Voici les différentes briques utilisé autour du projet :
|
||||
- _[Garage](https://garagehq.deuxfleurs.fr/)_ pour l'hébergement développé par l'association [Deuxfleurs](https://deuxfleurs.fr/)
|
||||
- _[Directus](https://directus.io/)_ pour l'administration
|
||||
- _[Drone](https://drone.io)_ pour la compilation automatique du projet
|
||||
- _[Matrix](https://fr.wikipedia.org/wiki/Matrix_(protocole))_ est un protocole ouvert pour de la communication en temps réel
|
||||
|
||||
Icon : https://www.svgrepo.com/collection/solar-linear-icons/
|
||||
|
22
index.html
22
index.html
@ -2,9 +2,29 @@
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/favicon/ms-icon-144x144.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Scores Ceiba</title>
|
||||
<meta name="description" content="L'application Scores de Ceiba">
|
||||
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
9489
package-lock.json
generated
9489
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@ -10,22 +10,24 @@
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@splidejs/vue-splide": "^0.5.18",
|
||||
"pinia": "^2.0.11",
|
||||
"@splidejs/vue-splide": "^0.6.12",
|
||||
"html-to-image": "^1.11.11",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"sass": "^1.49.9",
|
||||
"sass-loader": "^12.6.0",
|
||||
"sharp": "^0.30.3",
|
||||
"vue": "^3.2.31",
|
||||
"vue-router": "^4.0.12"
|
||||
"sass": "^1.75.0",
|
||||
"sass-loader": "^14.2.1",
|
||||
"sharp": "^0.33.3",
|
||||
"vite-plugin-pwa": "^0.19.8",
|
||||
"vue": "^3.4.26",
|
||||
"vue-router": "^4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.1.0",
|
||||
"@vitejs/plugin-vue": "^2.2.2",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@rushstack/eslint-patch": "^1.10.2",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"eslint": "^8.5.0",
|
||||
"eslint-plugin-vue": "^8.2.0",
|
||||
"prettier": "^2.5.1",
|
||||
"vite": "^2.8.4"
|
||||
"prettier": "^3.2.5",
|
||||
"vite": "^5.2.10"
|
||||
}
|
||||
}
|
||||
|
1
public/abacus.svg
Normal file
1
public/abacus.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#CCD6DD" d="M3 16v-2h30v2zm0 7v-2h30v2zm0 7v-2h30v2zM3 9V7h30v2z"/><path fill="#D5AB88" d="M35 33V1c0-.552-.448-1-1-1h-1c-.552 0-1 .448-1 1H4c0-.552-.448-1-1-1H2c-.552 0-1 .448-1 1v32h34zM4 4h28v29H4V4z"/><path fill="#3B94D9" d="M19 5.5c-.829 0-1.5.671-1.5 1.5 0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5c0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5c0-.829-.671-1.5-1.5-1.5S8.5 6.171 8.5 7c0-.829-.671-1.5-1.5-1.5S5.5 6.171 5.5 7v2c0 .829.671 1.5 1.5 1.5S8.5 9.829 8.5 9c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5.828 0 1.5-.671 1.5-1.5V7c0-.829-.672-1.5-1.5-1.5z"/><path fill="#BE1931" d="M19 12.5c-.829 0-1.5.671-1.5 1.5 0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5c0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5c0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5c0-.829-.671-1.5-1.5-1.5s-1.5.671-1.5 1.5v2c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5s1.5-.671 1.5-1.5c0 .829.671 1.5 1.5 1.5.828 0 1.5-.671 1.5-1.5v-2c0-.829-.672-1.5-1.5-1.5z"/><path fill="#5C913B" d="M19 19.5c-.829 0-1.5.672-1.5 1.5 0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5v2c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5.828 0 1.5-.672 1.5-1.5v-2c0-.828-.672-1.5-1.5-1.5z"/><path fill="#FFAC33" d="M19 26.5c-.829 0-1.5.672-1.5 1.5 0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5c0-.828-.671-1.5-1.5-1.5s-1.5.672-1.5 1.5v2c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5s1.5-.672 1.5-1.5c0 .828.671 1.5 1.5 1.5.828 0 1.5-.672 1.5-1.5v-2c0-.828-.672-1.5-1.5-1.5z"/><path fill="#3B94D9" d="M29 10.5c-.828 0-1.5-.671-1.5-1.5V7c0-.829.672-1.5 1.5-1.5s1.5.671 1.5 1.5v2c0 .829-.672 1.5-1.5 1.5z"/><path fill="#BE1931" d="M29 17.5c-.828 0-1.5-.671-1.5-1.5v-2c0-.829.672-1.5 1.5-1.5s1.5.671 1.5 1.5v2c0 .829-.672 1.5-1.5 1.5z"/><path fill="#5C913B" d="M29 24.5c-.828 0-1.5-.672-1.5-1.5v-2c0-.828.672-1.5 1.5-1.5s1.5.672 1.5 1.5v2c0 .828-.672 1.5-1.5 1.5z"/><path fill="#FFAC33" d="M29 31.5c-.828 0-1.5-.672-1.5-1.5v-2c0-.828.672-1.5 1.5-1.5s1.5.672 1.5 1.5v2c0 .828-.672 1.5-1.5 1.5z"/><path fill="#BF6952" d="M35 33H1c-.552 0-1 .448-1 1v1c0 .552.448 1 1 1h34c.552 0 1-.448 1-1v-1c0-.552-.448-1-1-1z"/><script xmlns=""/></svg>
|
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
2
public/favicon/browserconfig.xml
Normal file
2
public/favicon/browserconfig.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/favicon/ms-icon-70x70.png"/><square150x150logo src="/favicon/ms-icon-150x150.png"/><square310x310logo src="/favicon/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
41
public/favicon/manifest.json
Normal file
41
public/favicon/manifest.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/favicon\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/favicon\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/favicon\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/favicon\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/favicon\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/favicon\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
BIN
public/images/pwa-icon-256.png
Normal file
BIN
public/images/pwa-icon-256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
BIN
public/images/pwa-icon-512.png
Normal file
BIN
public/images/pwa-icon-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 220 KiB |
3
public/spin.svg
Normal file
3
public/spin.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||
<g><path d="M758.7,873c10.4,17.7,4.6,41.2-13.6,51.1c-18,10.4-40.7,4.3-50.9-13.7c-10.9-17.7-4.5-40.7,13.1-51.1C725.7,848.9,748.3,855.4,758.7,873L758.7,873z M537.9,952.8L537.9,952.8c0,20.4-16.9,37.5-38,37.5c-20.4,0-37.5-16.6-37.5-37.5v-26.2c0-20.9,17.1-37.5,37.5-37.5c20.8,0,38,16.6,38,37.5V952.8L537.9,952.8z M306.6,910.5L306.6,910.5c-10.7,18.5-33.7,24.4-51.4,13.9c-18.2-10.2-24.7-33.2-13.9-51.4l27.8-48.7c10.7-18,33.7-24.1,51.9-13.9c17.7,10.5,24.1,33.7,13.4,51.4L306.6,910.5L306.6,910.5z M127.3,759L127.3,759c-18.2,10.2-41.5,4-51.4-13.9c-10.7-17.7-4.6-41,13.3-51.4l75-43.4c17.9-9.9,41.2-4.3,51.3,13.9c10.2,17.7,4.1,41-13.9,51.4L127.3,759L127.3,759z M47.4,537.6L47.4,537.6c-20.8,0-37.4-16.9-37.4-37.5c0-20.9,16.6-37.7,37.4-37.7h116.8c20.8,0,37.5,16.9,37.5,37.5c0,20.9-16.6,37.7-37.5,37.7H47.4L47.4,537.6z M89.2,306.1L89.2,306.1c-18.2-10.2-24-33.2-13.3-51.1c9.9-18.2,33.2-24.4,51.4-13.9l126.8,73.6c18,10.2,23.9,33.2,14,50.8c-10.7,18.2-33.7,24.1-51.4,13.9L89.2,306.1L89.2,306.1z M241.3,126.7L241.3,126.7l88.3,153.4c10.8,17.9,33.7,24.4,51.7,13.7c17.9-10.2,23.8-33.5,13.3-51.4L306,89.2c-10.2-17.7-33.2-24.1-50.8-13.7C236.9,86,231.1,109.1,241.3,126.7L241.3,126.7z M462.4,47.5L462.4,47.5c0-20.3,17.1-37.7,37.5-37.7c20.8,0,38,16.9,38,37.7v176.7c0,20.9-16.9,37.7-38,38c-20.4,0-37.5-16.6-37.5-38V47.5L462.4,47.5z M693.6,89.2L693.6,89.2c10.7-18.2,33.5-24.1,51.5-13.9c18.2,10.2,24.6,33.2,13.8,51.4l-88.6,153.4c-9.8,17.9-33.4,24.4-51.3,13.9c-18-10.5-23.9-33.7-13.7-51.6L693.6,89.2L693.6,89.2z M873.5,241L873.5,241l-153.6,88.6c-17.9,10.2-24.1,33.2-14,51.4c10.7,17.7,33.8,23.5,51.4,13.7l153.7-88.6c17.6-10.2,24-33.2,13.4-51.1C914.3,236.7,891.2,230.3,873.5,241L873.5,241z M952.5,462.4L952.5,462.4c21.1,0,37.8,16.9,37.5,37.7c0,20.6-16.4,37.5-37.5,37.5h-177c-20.3,0-37.4-16.9-37.4-37.7c0-20.6,17.1-37.5,37.4-37.5H952.5L952.5,462.4z"/></g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
91
public/test.html
Normal file
91
public/test.html
Normal file
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.playable-code {
|
||||
background-color: #f4f7f8;
|
||||
border: none;
|
||||
border-left: 6px solid #558abb;
|
||||
border-width: medium medium medium 6px;
|
||||
color: #4d4e53;
|
||||
height: 100px;
|
||||
width: 90%;
|
||||
padding: 10px 10px 0;
|
||||
}
|
||||
|
||||
.playable-canvas {
|
||||
border: 1px solid #4d4e53;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.playable-buttons {
|
||||
text-align: right;
|
||||
width: 90%;
|
||||
padding: 5px 10px 5px 26px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<title>Navigator: share() method - sharing_files - code sample</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<label for="files">Select images to share:</label>
|
||||
<input id="files" type="file" accept="image/*" multiple />
|
||||
</div>
|
||||
<button id="share" type="button">Share your images!</button>
|
||||
<output id="output"></output>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
const input = document.getElementById("files");
|
||||
const output = document.getElementById("output");
|
||||
|
||||
document.getElementById("share").addEventListener("click", async () => {
|
||||
const files = input.files;
|
||||
|
||||
if (files.length === 0) {
|
||||
output.textContent = "No files selected.";
|
||||
return;
|
||||
}
|
||||
|
||||
// feature detecting navigator.canShare() also implies
|
||||
// the same for the navigator.share()
|
||||
if (!navigator.canShare) {
|
||||
output.textContent = `Your browser doesn't support the Web Share API.`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigator.canShare({ files })) {
|
||||
try {
|
||||
await navigator.share({
|
||||
files,
|
||||
title: "Images",
|
||||
text: "Beautiful images",
|
||||
});
|
||||
output.textContent = "Shared!";
|
||||
} catch (error) {
|
||||
output.textContent = `Error: ${error.message}`;
|
||||
}
|
||||
} else {
|
||||
output.textContent = `Your system doesn't support sharing these files.`;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -30,7 +30,33 @@ async function fetchAsset(uuid) {
|
||||
return fetch(url);
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
async function fetchCertitudesData() {
|
||||
const fields = ["*", "translations.*"];
|
||||
const url = `/items/certitudes?${fields
|
||||
.map((item) => `fields[]=${item}`)
|
||||
.join("&")}`;
|
||||
let certitudes = (await fetchJSONApi(url)).data;
|
||||
await fs.writeFile(
|
||||
"./src/certitudes.json",
|
||||
JSON.stringify(certitudes),
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
|
||||
async function fetchCertitudesResultsData() {
|
||||
const fields = ["*", "translations.*"];
|
||||
const url = `/items/certitudes_results?${fields
|
||||
.map((item) => `fields[]=${item}`)
|
||||
.join("&")}`;
|
||||
let certitudes = (await fetchJSONApi(url)).data;
|
||||
await fs.writeFile(
|
||||
"./src/certitudesResults.json",
|
||||
JSON.stringify(certitudes),
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
|
||||
async function fetchScoresData() {
|
||||
const fields = [
|
||||
"*",
|
||||
"translations.*",
|
||||
@ -47,28 +73,39 @@ async function fetchData() {
|
||||
const url = `/items/scores?${fields
|
||||
.map((item) => `fields[]=${item}`)
|
||||
.join("&")}`;
|
||||
const data = (await fetchJSONApi(url)).data;
|
||||
await fs.writeFile("./src/data.json", JSON.stringify(data), "utf8");
|
||||
let scores = (await fetchJSONApi(url)).data;
|
||||
if (process.env.NODE_ENV == "production") {
|
||||
console.log("Suppresion des scores avec le mode brouillon en production");
|
||||
scores = scores.filter((score) => !score.draft);
|
||||
} else if (process.env.NODE_ENV == "test") {
|
||||
console.log("Suppresion des scores sans l'environnement test");
|
||||
scores = scores.filter((score) => score.env_test);
|
||||
}
|
||||
await fs.writeFile("./src/data.json", JSON.stringify(scores), "utf8");
|
||||
|
||||
const folder = "public/answers";
|
||||
if (!existsSync(folder)) mkdirSync(folder);
|
||||
for (const score of data) {
|
||||
for (const score of scores) {
|
||||
const uuid_score = score.image;
|
||||
if (uuid_score) {
|
||||
console.log(`Score image : ${folder}/${uuid_score}`);
|
||||
const response = await fetchAsset(uuid_score);
|
||||
try {
|
||||
const thumbnail = sharp().resize({ height: 200 }).webp();
|
||||
await streamPipeline(
|
||||
response.body,
|
||||
thumbnail,
|
||||
createWriteStream(`${folder}/${uuid_score}.webp`),
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
for (const question of score.questions) {
|
||||
for (const answer of question.questions_id.answers) {
|
||||
const uuid = answer.answers_id.image;
|
||||
if (uuid) {
|
||||
console.log(`${folder}/${uuid}`);
|
||||
const response = await fetchAsset(uuid);
|
||||
try {
|
||||
const thumbnail = sharp().resize({ height: 200 }).webp();
|
||||
await streamPipeline(
|
||||
response.body,
|
||||
thumbnail,
|
||||
createWriteStream(`${folder}/${uuid}.webp`)
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
await downloadImage(uuid, `${folder}/${uuid}.webp`, { height: 200 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,4 +114,233 @@ async function fetchData() {
|
||||
// await sharp('src/assets/arbre.png').resize({ width: 440, height: 690 }).webp().toFile('public/arbre.webp')
|
||||
}
|
||||
|
||||
async function transformImage(response, path, options, format = "webp") {
|
||||
try {
|
||||
let thumbnail;
|
||||
console.log(path);
|
||||
if (format == "webp") {
|
||||
thumbnail = sharp().resize(options).webp();
|
||||
} else {
|
||||
thumbnail = sharp().resize(options).toFormat("png");
|
||||
}
|
||||
const stream = createWriteStream(path);
|
||||
await streamPipeline(response.body, thumbnail, stream);
|
||||
await stream;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadImage(uuid, path, options, format = "webp") {
|
||||
const response = await fetchAsset(uuid);
|
||||
await transformImage(response, path, options, format);
|
||||
}
|
||||
|
||||
async function fetchHomepageData() {
|
||||
const fields = ["*"];
|
||||
const url = `/items/homepage?${fields
|
||||
.map((item) => `fields[]=${item}`)
|
||||
.join("&")}`;
|
||||
const homepage = (await fetchJSONApi(url)).data;
|
||||
|
||||
await downloadImage(homepage.image, `public/homepage.webp`, {
|
||||
width: 1280,
|
||||
height: 720,
|
||||
fit: sharp.fit.cover,
|
||||
});
|
||||
|
||||
const favicons = [
|
||||
{
|
||||
path: `public/favicon/android-icon-192x192.png`,
|
||||
options: {
|
||||
width: 192,
|
||||
height: 192,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-57x57.png`,
|
||||
options: {
|
||||
width: 57,
|
||||
height: 57,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-60x60.png`,
|
||||
options: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-72x72.png`,
|
||||
options: {
|
||||
width: 72,
|
||||
height: 72,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-76x76.png`,
|
||||
options: {
|
||||
width: 76,
|
||||
height: 76,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-114x114.png`,
|
||||
options: {
|
||||
width: 114,
|
||||
height: 114,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-120x120.png`,
|
||||
options: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-144x144.png`,
|
||||
options: {
|
||||
width: 144,
|
||||
height: 144,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-152x152.png`,
|
||||
options: {
|
||||
width: 152,
|
||||
height: 152,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/apple-icon-180x180.png`,
|
||||
options: {
|
||||
width: 180,
|
||||
height: 180,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/favicon-16x16.png`,
|
||||
options: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/favicon-32x32.png`,
|
||||
options: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/favicon-96x96.png`,
|
||||
options: {
|
||||
width: 96,
|
||||
height: 96,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/favicon-256x256.png`,
|
||||
options: {
|
||||
width: 256,
|
||||
height: 256,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/ms-icon-70x70.png`,
|
||||
options: {
|
||||
width: 70,
|
||||
height: 70,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/ms-icon-144x144.png`,
|
||||
options: {
|
||||
width: 144,
|
||||
height: 144,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/ms-icon-150x150.png`,
|
||||
options: {
|
||||
width: 150,
|
||||
height: 150,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
{
|
||||
path: `public/favicon/ms-icon-310x310.png`,
|
||||
options: {
|
||||
width: 310,
|
||||
height: 310,
|
||||
fit: sharp.fit.contain,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
},
|
||||
format: "png",
|
||||
},
|
||||
];
|
||||
for (const favicon of favicons) {
|
||||
downloadImage(homepage.logo, favicon.path, favicon.options, favicon.format);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
await fetchHomepageData();
|
||||
await fetchCertitudesData();
|
||||
await fetchCertitudesResultsData();
|
||||
await fetchScoresData();
|
||||
}
|
||||
|
||||
fetchData();
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 626 KiB |
@ -6,31 +6,52 @@
|
||||
--color-black: #000000;
|
||||
--color-green: rgb(118, 148, 67);
|
||||
|
||||
--header-size-small: 64px;
|
||||
--header-size-small: 48px;
|
||||
--header-size-big: 128px;
|
||||
--header-size: var(--header-size-small);
|
||||
|
||||
--footer-size: 48px;
|
||||
|
||||
--color-red: #c82606;
|
||||
--color-orange: #df6a0f;
|
||||
--color-light-green: #70bf41;
|
||||
--color-dark-green: #00882b;
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
:root, body.theme-light {
|
||||
--color-header-background: var(--color-green);
|
||||
--color-header-text: var(--color-white);
|
||||
--color-background: var(--color-white);
|
||||
--color-text: var(--color-black);
|
||||
--color-highlight: var(--color-green);
|
||||
--header-size: var(--header-size-small);
|
||||
--color-highlight-background: var(--color-green);
|
||||
--color-highlight-text: var(--color-white);
|
||||
--color-highlight-text-invert: var(--color-black);
|
||||
}
|
||||
|
||||
body.theme-dark {
|
||||
--color-header-background: var(--color-green);
|
||||
--color-header-text: var(--color-black);
|
||||
--color-background: var(--color-black);
|
||||
--color-text: var(--color-white);
|
||||
--color-highlight-background: var(--color-green);
|
||||
--color-highlight-text: var(--color-black);
|
||||
--color-highlight-text-invert: var(--color-white);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-header-background: var(--color-green);
|
||||
--color-header-text: var(--color-black);
|
||||
--color-background: var(--color-black);
|
||||
--color-text: var(--color-white);
|
||||
--color-highlight-background: var(--color-green);
|
||||
--color-highlight-text: var(--color-black);
|
||||
--color-highlight-text-invert: var(--color-white);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@media (min-height: 1000px) {
|
||||
:root {
|
||||
--header-size: var(--header-size-big);
|
||||
}
|
||||
@ -66,3 +87,53 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
body.print {
|
||||
--color-highlight-background: var(--color-white);
|
||||
--color-highlight-text: var(--color-black);
|
||||
--color-highlight-text-invert: var(--color-white);
|
||||
--color-header-background: var(--color-white);
|
||||
--color-header-text: var(--color-black);
|
||||
}
|
||||
|
||||
.print .no-print {
|
||||
display: none
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
padding: .5rem;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
border: none;
|
||||
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);
|
||||
cursor: pointer;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.btn svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
header svg.color-text [stroke] {
|
||||
stroke: var(--color-header-text);
|
||||
}
|
||||
|
||||
header svg.color-text [fill]:not([fill=none]) {
|
||||
fill: var(--color-header-text)
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bg-red { background: var(--color-red); }
|
||||
.bg-orange { background: var(--color-orange); }
|
||||
.bg-light-green { background: var(--color-light-green); }
|
||||
.bg-dark-green { background: var(--color-dark-green); }
|
||||
|
191
src/components/Certitude.vue
Normal file
191
src/components/Certitude.vue
Normal file
@ -0,0 +1,191 @@
|
||||
<script setup>
|
||||
import { ref, computed, watchEffect } from "vue";
|
||||
import { useStore } from "@/stores"; // adapte le chemin si besoin
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const props = defineProps({
|
||||
certitude: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(["answerSelected", "nextQuestion"]);
|
||||
|
||||
const selectedWeight = ref(null);
|
||||
|
||||
// Utilise la langue du store
|
||||
const language = computed(() => store.language || "fr-FR");
|
||||
|
||||
// Recherche la bonne traduction selon la langue courante
|
||||
const translation = computed(() => {
|
||||
return (
|
||||
props.certitude.translations.find(
|
||||
(t) => t.languages_code === language.value,
|
||||
) ||
|
||||
// Fallback en français
|
||||
props.certitude.translations.find((t) => t.languages_code === "fr-FR") ||
|
||||
// Fallback générique
|
||||
props.certitude.translations[0]
|
||||
);
|
||||
});
|
||||
|
||||
// Regroupe les réponses avec leurs poids
|
||||
const answers = computed(() => {
|
||||
return [1, 2, 3].map((i) => ({
|
||||
id: i,
|
||||
title: translation.value[`answer${i}`],
|
||||
weight: props.certitude[`weight${i}`],
|
||||
}));
|
||||
});
|
||||
|
||||
function selectAnswer(answer) {
|
||||
selectedWeight.value = answer.weight;
|
||||
emits("answerSelected", props.certitude, selectedWeight.value);
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (answers.value.length && selectedWeight.value === null) {
|
||||
selectAnswer(answers.value[0]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="center">
|
||||
<legend>{{ translation.title }}</legend>
|
||||
<div class="description" v-html="translation.description"></div>
|
||||
|
||||
<ul class="choices">
|
||||
<li class="choice" v-for="answer in answers" :key="answer.id">
|
||||
<input
|
||||
type="radio"
|
||||
:id="`certitude_${certitude.id}_answer_${answer.id}`"
|
||||
:name="`certitude_${certitude.id}`"
|
||||
:value="answer.weight"
|
||||
v-model="selectedWeight"
|
||||
@change="selectAnswer(answer)"
|
||||
@click="$emit('nextQuestion')"
|
||||
/>
|
||||
<label :for="`certitude_${certitude.id}_answer_${answer.id}`">
|
||||
<div>{{ answer.title }}</div>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btns">
|
||||
<button class="btn next" @click="$emit('nextQuestion')">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 40 40"
|
||||
width="40"
|
||||
height="40"
|
||||
>
|
||||
<path
|
||||
d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
legend
|
||||
text-align: center
|
||||
font-size: 1.4rem
|
||||
line-height: 2rem
|
||||
font-weight: bold
|
||||
width: 100%
|
||||
|
||||
.description
|
||||
text-align: center
|
||||
padding: 1rem
|
||||
font-size: 1rem
|
||||
|
||||
.choices
|
||||
list-style-type: none
|
||||
text-align: left
|
||||
display: inline-block
|
||||
padding-left: 0
|
||||
|
||||
label
|
||||
cursor: pointer
|
||||
display: block
|
||||
|
||||
input[type=radio]
|
||||
display: none
|
||||
|
||||
& + label > div
|
||||
position: relative
|
||||
padding: .2rem .2rem .2rem 2rem
|
||||
|
||||
& + label > div::before,
|
||||
& + label > div::after
|
||||
display: block
|
||||
position: absolute
|
||||
box-sizing: border-box
|
||||
content:''
|
||||
border-radius: 1rem
|
||||
|
||||
& + label > div::before
|
||||
top: .5rem
|
||||
left: 0
|
||||
background-color: var(--color-green)
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
|
||||
& + label > div::after
|
||||
top: calc(3px + .5rem)
|
||||
left: 3px
|
||||
width: calc(1rem - 6px)
|
||||
height: calc(1rem - 6px)
|
||||
|
||||
&:checked + label > div
|
||||
text-shadow: -0.06ex 0 0 currentColor, 0.06ex 0 0 currentColor
|
||||
|
||||
&:not(:checked) + label > div::before
|
||||
background-color: var(--color-green)
|
||||
|
||||
&:not(:checked) + label > div::after
|
||||
background-color: white
|
||||
|
||||
.main
|
||||
height: 100%
|
||||
max-width: 100%
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: space-around
|
||||
align-items: center
|
||||
|
||||
.center
|
||||
width: 100%
|
||||
text-align: center
|
||||
|
||||
.btns
|
||||
width: 400px
|
||||
max-width: 100%
|
||||
min-width: 280px
|
||||
position: relative
|
||||
margin: 0 auto
|
||||
|
||||
.next
|
||||
background: var(--color-highlight-background)
|
||||
bottom: 1rem
|
||||
right: 1rem
|
||||
width: 3rem
|
||||
height: 3rem
|
||||
opacity: .8
|
||||
|
||||
&:hover
|
||||
opacity: 1
|
||||
|
||||
svg
|
||||
width: 80%
|
||||
height: 80%
|
||||
transform: rotate(90deg)
|
||||
fill: var(--color-highlight-text)
|
||||
</style>
|
@ -17,7 +17,7 @@ const answerWeight = ref(props.question.weight);
|
||||
|
||||
function selectAnswer(answer) {
|
||||
const answerIndex = props.question.answers.findIndex(
|
||||
(a) => a.id === answer.id
|
||||
(a) => a.id === answer.id,
|
||||
);
|
||||
slides.value.splide.go(answerIndex);
|
||||
}
|
||||
@ -26,6 +26,38 @@ function slideMove(splide, newIndex) {
|
||||
answerWeight.value = props.question.answers[newIndex].weight;
|
||||
emits("answerSelected", props.question, answerWeight);
|
||||
}
|
||||
const displayPopup = ref(false);
|
||||
function showHidePopup() {
|
||||
displayPopup.value = !displayPopup.value;
|
||||
}
|
||||
function validatePopup() {
|
||||
const calcule = Math.round((h.value * 100) / d.value);
|
||||
const regexp = /[^0-9]*([0-9]{2})/g;
|
||||
const answersLength = props.question.answers.length;
|
||||
const answerIndex = props.question.answers.find((answer, index) => {
|
||||
const values = Array.from(answer.title.matchAll(regexp), (m) => m[1]);
|
||||
if (values.length > 0) {
|
||||
const min = values.length == 1 ? 0 : values[0];
|
||||
const max = values.length == 1 ? values[0] : values[1];
|
||||
if (calcule >= min && calcule <= max) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (answersLength == index + 1) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const answer = document.querySelector(
|
||||
"input[id=" +
|
||||
`question_${props.question.id}_answer_${answerIndex.id}` +
|
||||
"]",
|
||||
);
|
||||
answer.checked = true;
|
||||
answer.dispatchEvent(new Event("change"));
|
||||
showHidePopup();
|
||||
}
|
||||
const h = ref();
|
||||
const d = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -41,11 +73,7 @@ function slideMove(splide, newIndex) {
|
||||
:id="`question_${question.id}`"
|
||||
ref="slides"
|
||||
>
|
||||
<SplideSlide
|
||||
v-for="answer in question.answers"
|
||||
:key="answer.id"
|
||||
@click="$emit('nextQuestion')"
|
||||
>
|
||||
<SplideSlide v-for="answer in question.answers" :key="answer.id">
|
||||
<img height="200" :src="`/answers/${answer.image}.webp`" />
|
||||
</SplideSlide>
|
||||
</Splide>
|
||||
@ -53,8 +81,12 @@ function slideMove(splide, newIndex) {
|
||||
</div>
|
||||
|
||||
<template v-if="question.answers">
|
||||
<ul class="choices">
|
||||
<li class="choice" v-for="answer in question.answers" :key="answer.id">
|
||||
<ul class="choices">
|
||||
<li
|
||||
class="choice"
|
||||
v-for="answer in question.answers"
|
||||
:key="answer.id"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
:data-answerId="answer.id"
|
||||
@ -66,16 +98,138 @@ function slideMove(splide, newIndex) {
|
||||
@click="nextQuestion"
|
||||
/>
|
||||
<label :for="`question_${question.id}_answer_${answer.id}`">
|
||||
{{ answer.title }}
|
||||
<div>
|
||||
{{ answer.title }}
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btns">
|
||||
<template v-if="question.function == 'rapport_hd'">
|
||||
<button class="btn calculette" @click="showHidePopup">
|
||||
<img src="/abacus.svg" alt="" />
|
||||
</button>
|
||||
</template>
|
||||
<button class="btn next" @click="$emit('nextQuestion')">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 40 40"
|
||||
width="40"
|
||||
height="40"
|
||||
>
|
||||
<path
|
||||
d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<template v-if="displayPopup">
|
||||
<div class="popup">
|
||||
<button class="btn close" @click="showHidePopup">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
||||
<path
|
||||
d="M21.529 18.006l8.238-8.238c.977-.976.977-2.559 0-3.535-.977-.977-2.559-.977-3.535 0l-8.238 8.238-8.238-8.238c-.976-.977-2.56-.977-3.535 0-.977.976-.977 2.559 0 3.535l8.238 8.238-8.258 8.258c-.977.977-.977 2.559 0 3.535.488.488 1.128.732 1.768.732s1.28-.244 1.768-.732l8.258-8.259 8.238 8.238c.488.488 1.128.732 1.768.732s1.279-.244 1.768-.732c.977-.977.977-2.559 0-3.535l-8.24-8.237z"
|
||||
fill="#000"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<label for="H">H (m)</label>
|
||||
<input v-model="h" type="number" name="H" />
|
||||
<label for="D">D (cm)</label>
|
||||
<input v-model="d" type="number" name="D" />
|
||||
<p v-if="d && d != 0">≃ {{ Math.round((h * 100) / d) }}</p>
|
||||
<p v-if="!d || d == 0" class="no-visible"></p>
|
||||
<button class="btn equal" @click="validatePopup">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
||||
<path
|
||||
fill="#31373D"
|
||||
d="M34.459 1.375c-1.391-.902-3.248-.506-4.149.884L13.5 28.17l-8.198-7.58c-1.217-1.125-3.114-1.051-4.239.166-1.125 1.216-1.051 3.115.166 4.239l10.764 9.952s.309.266.452.359c.504.328 1.07.484 1.63.484.982 0 1.945-.482 2.52-1.368L35.343 5.524c.902-1.39.506-3.248-.884-4.149z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
.btns
|
||||
width: 400px
|
||||
max-width: 100%
|
||||
min-width: 280px
|
||||
position: relative
|
||||
margin: 0 auto
|
||||
|
||||
.popup
|
||||
position: absolute
|
||||
background: var(--color-highlight-background)
|
||||
color: var(--color-highlight-text)
|
||||
top: 0
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
z-index: 100
|
||||
display: flex
|
||||
flex-direction: column
|
||||
padding: 1rem
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
p
|
||||
padding: 1rem
|
||||
margin: 1rem
|
||||
border: 1px solid var(--color-highlight-text)
|
||||
font-size: 2rem
|
||||
|
||||
&.no-visible
|
||||
border: 1px solid transparent
|
||||
|
||||
svg path
|
||||
fill: var(--color-highlight-background)
|
||||
.close
|
||||
top: 1rem
|
||||
right: 1rem
|
||||
|
||||
|
||||
.equal
|
||||
position: relative
|
||||
|
||||
input
|
||||
padding: .4rem
|
||||
text-align: center
|
||||
font-size: 1rem
|
||||
width: 5rem
|
||||
|
||||
.calculette
|
||||
background: var(--color-highlight-background)
|
||||
bottom: 1rem
|
||||
left: 1rem
|
||||
width: 4rem
|
||||
height: 4rem
|
||||
|
||||
img
|
||||
width: 80%
|
||||
height: 80%
|
||||
|
||||
.next
|
||||
background: var(--color-highlight-background)
|
||||
bottom: 1rem
|
||||
right: 1rem
|
||||
width: 3rem
|
||||
height: 3rem
|
||||
opacity: .8
|
||||
|
||||
&:hover
|
||||
opacity: 1
|
||||
|
||||
svg
|
||||
width: 80%
|
||||
height: 80%
|
||||
transform: rotate(90deg)
|
||||
fill: var(--color-highlight-text)
|
||||
|
||||
.splide__arrow
|
||||
background: transparent
|
||||
border: 3px solid var(--color-green)
|
||||
@ -89,6 +243,7 @@ function slideMove(splide, newIndex) {
|
||||
width: 1.6rem
|
||||
.splide__pagination
|
||||
bottom: -1.5em
|
||||
display: none
|
||||
.splide__pagination__page
|
||||
width: .7rem
|
||||
height: .7rem
|
||||
@ -104,7 +259,8 @@ legend
|
||||
text-align: center
|
||||
font-size: 1.4rem
|
||||
line-height: 2rem
|
||||
margin: 1rem
|
||||
font-weight: bold
|
||||
width: 100%
|
||||
|
||||
.choices
|
||||
list-style-type: none
|
||||
@ -112,34 +268,40 @@ legend
|
||||
display: inline-block
|
||||
padding-left: 0
|
||||
|
||||
label
|
||||
cursor: pointer
|
||||
display: block
|
||||
|
||||
input[type=radio]
|
||||
display: none
|
||||
|
||||
& + label
|
||||
& + label > div
|
||||
position: relative
|
||||
padding-left: 2rem
|
||||
& + label::before,
|
||||
& + label::after
|
||||
padding: .2rem .2rem .2rem 2rem
|
||||
& + label > div::before,
|
||||
& + label > div::after
|
||||
display: block
|
||||
position: absolute
|
||||
box-sizing: border-box
|
||||
content:''
|
||||
border-radius: 1rem
|
||||
& + label::before
|
||||
bottom: 0
|
||||
& + label > div::before
|
||||
top: .5rem
|
||||
left: 0
|
||||
background-color: var(--color-green)
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
& + label::after
|
||||
bottom: 3px
|
||||
& + label > div::after
|
||||
top: calc(3px + .5rem)
|
||||
left: 3px
|
||||
width: calc(1rem - 6px)
|
||||
height: calc(1rem - 6px)
|
||||
&:checked + label::before
|
||||
background-color: white
|
||||
&:checked + label::after
|
||||
&:checked + label > div
|
||||
text-shadow: -0.06ex 0 0 currentColor, 0.06ex 0 0 currentColor
|
||||
&:not(:checked) + label > div::before
|
||||
background-color: var(--color-green)
|
||||
&:not(:checked) + label > div::after
|
||||
background-color: white
|
||||
|
||||
.main
|
||||
height: 100%
|
||||
@ -159,6 +321,9 @@ legend
|
||||
max-width: 100%
|
||||
min-width: 280px
|
||||
|
||||
@media (max-height: 600px)
|
||||
margin: 1rem auto
|
||||
|
||||
h2
|
||||
font-size: 2rem
|
||||
|
||||
|
@ -1,14 +1,18 @@
|
||||
<script setup>
|
||||
import data from "@/data.json";
|
||||
import certitudes from "@/certitudes.json";
|
||||
import certitudesResults from "@/certitudesResults.json";
|
||||
|
||||
import { ref, computed } from "vue";
|
||||
import { ref, computed, watch } from "vue";
|
||||
|
||||
import { useStore } from "@/stores";
|
||||
|
||||
import { Splide, SplideSlide } from "@splidejs/vue-splide";
|
||||
import Question from "./Question.vue";
|
||||
import Certitude from "./Certitude.vue";
|
||||
import "@splidejs/splide/dist/css/splide.min.css";
|
||||
import ScoreHeader from "./ScoreHeader.vue";
|
||||
// import { toPng } from "html-to-image";
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
@ -28,7 +32,7 @@ function formatAnswers(answers) {
|
||||
.map((answer) => answer.answers_id)
|
||||
.map((answer) => {
|
||||
const translation = answer.translations.filter(
|
||||
(item) => item.languages_code == language
|
||||
(item) => item.languages_code == language,
|
||||
);
|
||||
return {
|
||||
id: answer.id,
|
||||
@ -44,20 +48,25 @@ function formatScore(score) {
|
||||
.map((question) => question.questions_id)
|
||||
.map((question) => {
|
||||
const translation = question.translations.filter(
|
||||
(item) => item.languages_code == language
|
||||
(item) => item.languages_code == language,
|
||||
);
|
||||
const answers = formatAnswers(question.answers);
|
||||
return {
|
||||
id: question.id,
|
||||
weight: answers[0].weight,
|
||||
title: translation.length > 0 ? translation[0].title : question.title,
|
||||
function: question.function,
|
||||
answers: answers,
|
||||
splide: ref(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const title = score ? score.title : "";
|
||||
function getTranslation(translations, key) {
|
||||
return translations.find((translation) => translation[key] == store.language);
|
||||
}
|
||||
const trad = getTranslation(score.translations, "languages_id");
|
||||
const title = score ? trad.title : "";
|
||||
const link = score ? trad.link : "";
|
||||
const questions = ref(formatScore(score));
|
||||
|
||||
const scoreSum = computed(() => {
|
||||
@ -66,14 +75,14 @@ const scoreSum = computed(() => {
|
||||
.reduce((value, currentValue) => value + currentValue, 0);
|
||||
});
|
||||
const displayScoreResult = computed(
|
||||
() => !questions.value.filter((q) => q.weight == null).length
|
||||
() => !questions.value.filter((q) => q.weight == null).length,
|
||||
);
|
||||
function getResultsFromScore(score) {
|
||||
return score.results
|
||||
.map((result) => result.results_id)
|
||||
.map((result) => {
|
||||
const translation = result.translations.filter(
|
||||
(item) => item.languages_code == language
|
||||
(item) => item.languages_code == language,
|
||||
);
|
||||
return {
|
||||
id: result.id,
|
||||
@ -83,8 +92,10 @@ function getResultsFromScore(score) {
|
||||
effets: translation.length > 0 ? translation[0].effets : "",
|
||||
facteur: translation.length > 0 ? translation[0].facteur : "",
|
||||
pde: translation.length > 0 ? translation[0].pde : "",
|
||||
title: translation.length > 0 ? translation[0].title : "",
|
||||
};
|
||||
});
|
||||
})
|
||||
.reverse();
|
||||
}
|
||||
const results = ref(getResultsFromScore(score));
|
||||
const result = computed(() =>
|
||||
@ -92,12 +103,12 @@ const result = computed(() =>
|
||||
? results.value
|
||||
.filter((r) => !r.min || r.min <= scoreSum.value)
|
||||
.filter((r) => !r.max || r.max >= scoreSum.value)[0]
|
||||
: null
|
||||
: null,
|
||||
);
|
||||
function goQuestionSlide(question) {
|
||||
console.log(slides.value);
|
||||
slides.value.go(
|
||||
questions.value.findIndex((element) => element.id === question.id)
|
||||
questions.value.findIndex((element) => element.id === question.id),
|
||||
);
|
||||
}
|
||||
function answerSelected(question, answerWeight) {
|
||||
@ -107,13 +118,86 @@ function answerSelected(question, answerWeight) {
|
||||
function nextQuestion() {
|
||||
setTimeout(() => {
|
||||
slides.value.go(">");
|
||||
console.log(slides)
|
||||
// console.log(slides);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// const saveAs = (blob, fileName) => {
|
||||
// var elem = window.document.createElement("a");
|
||||
// elem.href = blob;
|
||||
// elem.download = fileName;
|
||||
// elem.style = "display:none;";
|
||||
// (document.body || document.documentElement).appendChild(elem);
|
||||
// if (typeof elem.click === "function") {
|
||||
// elem.click();
|
||||
// } else {
|
||||
// elem.target = "_blank";
|
||||
// elem.dispatchEvent(
|
||||
// new MouseEvent("click", {
|
||||
// view: window,
|
||||
// bubbles: true,
|
||||
// cancelable: true,
|
||||
// }),
|
||||
// );
|
||||
// }
|
||||
// URL.revokeObjectURL(elem.href);
|
||||
// elem.remove();
|
||||
// };
|
||||
|
||||
// const sharing = ref(false);
|
||||
// async function share() {
|
||||
// sharing.value = true;
|
||||
// const filter = (node) => {
|
||||
// const exclusionClasses = ["btn"];
|
||||
// return !exclusionClasses.some((classname) =>
|
||||
// node.classList?.contains(classname),
|
||||
// );
|
||||
// };
|
||||
// const body = document.querySelector("body");
|
||||
// body.classList.add("print");
|
||||
// const dataUrl = await toPng(body, { filter: filter });
|
||||
// body.classList.remove("print");
|
||||
// const fileName = new Date()
|
||||
// .toISOString()
|
||||
// .replace(/T/, "_")
|
||||
// .replace(/\..+/, "")
|
||||
// .replaceAll(":", "-");
|
||||
// saveAs(dataUrl, `Ceiba-score-${fileName}.png`);
|
||||
// sharing.value = false;
|
||||
// }
|
||||
|
||||
const displayCertitude = ref(false);
|
||||
const weightCertitudes = ref(new Array(certitudes.length).fill(0));
|
||||
const weightAllCertitudes = ref(0);
|
||||
const certitudeResult = ref(selectCertitudeResult());
|
||||
function selectCertitudeResult() {
|
||||
const certitude = certitudesResults.find(
|
||||
(result) =>
|
||||
result.weight_min <= weightAllCertitudes.value &&
|
||||
result.weight_max >= weightAllCertitudes.value,
|
||||
);
|
||||
const certitudeTrad = certitude?.translations.find(
|
||||
(translation) => translation.languages_code == language,
|
||||
);
|
||||
return { ...certitudeTrad, color: certitude.color };
|
||||
}
|
||||
function displayCertitudeQuestions() {
|
||||
displayCertitude.value = !displayCertitude.value;
|
||||
}
|
||||
function answerSelectedCertitude(question, answerWeight) {
|
||||
weightCertitudes.value[question.sort - 1] = answerWeight;
|
||||
weightAllCertitudes.value = weightCertitudes.value.reduce(
|
||||
(accumulator, curr) => accumulator + curr,
|
||||
0,
|
||||
);
|
||||
}
|
||||
watch(weightAllCertitudes, () => {
|
||||
certitudeResult.value = selectCertitudeResult();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ScoreHeader v-if="title" :title="title" />
|
||||
<ScoreHeader v-if="title" :title="title" :link="link" />
|
||||
<Splide
|
||||
ref="slides"
|
||||
class="questions"
|
||||
@ -135,26 +219,76 @@ function nextQuestion() {
|
||||
@nextQuestion="nextQuestion"
|
||||
/>
|
||||
</SplideSlide>
|
||||
<template v-if="displayCertitude">
|
||||
<SplideSlide v-for="certitude in certitudes" :key="certitude.id">
|
||||
<Certitude
|
||||
:certitude="certitude"
|
||||
@answerSelected="answerSelectedCertitude"
|
||||
@nextQuestion="nextQuestion"
|
||||
/>
|
||||
</SplideSlide>
|
||||
</template>
|
||||
<SplideSlide class="latest">
|
||||
<template v-if="displayScoreResult && result">
|
||||
<h2 class="center">Probabilité d'échec</h2>
|
||||
<h2 class="center">{{ result.pde_qtra }}</h2>
|
||||
<div class="gradient">
|
||||
<div
|
||||
v-for="(item, index) in [...Array(7).keys()]"
|
||||
:class="{ active: result && result.pde_qtra === index + 1 }"
|
||||
:key="item"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
<div>
|
||||
<h2 class="center">{{ trad.result_title }}</h2>
|
||||
<h2 class="center">{{ result.title }}</h2>
|
||||
<div :class="'gradient size-' + results.length">
|
||||
<div
|
||||
v-for="item in results"
|
||||
:class="{ active: result && result.pde_qtra === item.pde_qtra }"
|
||||
:key="item"
|
||||
:data-title="trad.result_sigle"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<p>Rappel des paramètres choisis :</p>
|
||||
<ul>
|
||||
<li v-for="question in questions" :key="question.id">
|
||||
{{ question.title }} : {{ question.answers.find((answer) => answer.weight === question.weight).title }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="details">
|
||||
<p>{{ trad.result_params }} :</p>
|
||||
<br />
|
||||
<ul>
|
||||
<li v-for="question in questions" :key="question.id">
|
||||
{{ question.title }} :
|
||||
{{
|
||||
question.answers.find(
|
||||
(answer) => answer.weight === question.weight,
|
||||
).title
|
||||
}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="certitude_result">
|
||||
Niveau de certitude
|
||||
<button
|
||||
@click="displayCertitudeQuestions"
|
||||
:class="'bg-' + certitudeResult.color"
|
||||
>
|
||||
<span>{{ certitudeResult?.niveau }} </span>
|
||||
</button>
|
||||
</div>
|
||||
<!--button class="btn download" @click="() => share()" v-if="!sharing">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
||||
<path
|
||||
fill="#D99E82"
|
||||
d="M36 32c0 2.209-1.791 4-4 4H4c-2.209 0-4-1.791-4-4v-9c0-2.209.791-3 3-3h30c2.209 0 3 .791 3 3v9z"
|
||||
/>
|
||||
<path
|
||||
fill="#662113"
|
||||
d="M25 20c0 3.866-3.134 7-7 7s-7-3.134-7-7h14z"
|
||||
/>
|
||||
<path
|
||||
fill="#C1694F"
|
||||
d="M4 36h28c2.209 0 4-1.791 4-4H0c0 2.209 1.791 4 4 4z"
|
||||
/>
|
||||
<path
|
||||
fill="#77B255"
|
||||
d="M26.716 8h-4.783V2c0-1.105-.896-2-2-2h-4.001c-1.104 0-1.999.896-1.999 2v6H9.148c-1.223 0-1.516.623-.651 1.489l7.863 7.863c.865.865 2.28.865 3.146 0l7.863-7.863C28.232 8.623 27.94 8 26.716 8z"
|
||||
/>
|
||||
</svg>
|
||||
</button-->
|
||||
<!-- <button class="btn spin" v-if="sharing">
|
||||
<img src="/spin.svg" />
|
||||
</button> -->
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
@ -187,8 +321,61 @@ function nextQuestion() {
|
||||
</template>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.certitude_result
|
||||
padding-top: 1rem
|
||||
font-size: 1.1rem
|
||||
text-align: center
|
||||
color: var(--color-highlight-text)
|
||||
& *
|
||||
font-weight: 800
|
||||
button
|
||||
display: flex
|
||||
width: 100%
|
||||
color: var(--color-highlight-text)
|
||||
justify-content: center
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
margin: .2rem auto 0
|
||||
border-radius: 0
|
||||
border: none
|
||||
font-weight: 900 !important
|
||||
font-size: 1.1rem
|
||||
padding: .3rem
|
||||
|
||||
.spin
|
||||
bottom: 1.5rem
|
||||
right: 1.5rem
|
||||
img
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
width: 30px
|
||||
height: 30px
|
||||
margin: -15px 0 0 -15px
|
||||
-webkit-animation: spin 2s linear infinite
|
||||
-moz-animation: spin 2s linear infinite
|
||||
animation: spin 2s linear infinite
|
||||
|
||||
@-moz-keyframes spin
|
||||
100%
|
||||
-moz-transform: rotate(360deg)
|
||||
|
||||
@-webkit-keyframes spin
|
||||
100%
|
||||
-webkit-transform: rotate(360deg)
|
||||
|
||||
@keyframes spin
|
||||
100%
|
||||
-webkit-transform: rotate(360deg)
|
||||
transform: rotate(360deg)
|
||||
|
||||
|
||||
.center
|
||||
text-align: center
|
||||
.download
|
||||
bottom: 1.5rem
|
||||
right: 1.5rem
|
||||
opacity: .7
|
||||
.noscore
|
||||
display: flex
|
||||
justify-content: center
|
||||
@ -213,8 +400,6 @@ function nextQuestion() {
|
||||
|
||||
|
||||
.splide__slide
|
||||
background: white
|
||||
color: black
|
||||
position: relative
|
||||
padding: 1rem
|
||||
|
||||
@ -231,37 +416,66 @@ label
|
||||
padding: .3rem
|
||||
|
||||
.latest
|
||||
background-color: var(--color-green)
|
||||
color: var(--color-white)
|
||||
text-align: center
|
||||
background-color: var(--color-highlight-background)
|
||||
color: var(--color-highlight-text)
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
h2
|
||||
font-size: 2rem
|
||||
font-size: 1.5rem
|
||||
font-weight: bold
|
||||
line-height: 2.4rem
|
||||
& + h2
|
||||
line-height: 2rem
|
||||
line-height: 3rem
|
||||
font-size: 2.6rem
|
||||
|
||||
@media (max-height: 600px)
|
||||
font-size: 1.5rem
|
||||
& + h2
|
||||
font-size: 2rem
|
||||
|
||||
ul
|
||||
text-align: left
|
||||
padding-left: 1.5rem
|
||||
list-style-type: disc
|
||||
|
||||
.details
|
||||
text-align: left
|
||||
display: inline-block
|
||||
text-align: left !important
|
||||
font-size: 1.1rem
|
||||
line-height: normal
|
||||
background: var(--color-highlight-background)
|
||||
border: 1px solid var(--color-highlight-text)
|
||||
padding: 1rem
|
||||
background: rgba(0,0,0,0.2)
|
||||
|
||||
li
|
||||
line-height: 1.5rem
|
||||
|
||||
.gradient
|
||||
padding: 0 1rem
|
||||
height: 3rem
|
||||
height: 2.5rem
|
||||
background-image: linear-gradient(to right, red, red, rgb(255, 255, 0), rgb(255, 255, 0), green, green)
|
||||
display: flex
|
||||
margin: 2.5rem auto
|
||||
margin: 1.5rem auto
|
||||
align-items: center
|
||||
border-radius: 3px
|
||||
max-width: 30rem
|
||||
color: var(--color-black)
|
||||
text-shadow: 1px 1px 4px var(--color-highlight-text-invert),-1px -1px 4px var(--color-highlight-text-invert), -1px 1px 4px var(--color-highlight-text-invert), 1px -1px 4px var(--color-highlight-text-invert)
|
||||
color: var(--color-highlight-text)
|
||||
|
||||
&.size-3 div
|
||||
width: calc(100%/3)
|
||||
&.size-4 div
|
||||
width: calc(100%/4)
|
||||
&.size-5 div
|
||||
width: calc(100%/5)
|
||||
&.size-6 div
|
||||
width: calc(100%/6)
|
||||
&.size-7 div
|
||||
width: calc(100%/7)
|
||||
|
||||
div
|
||||
width: calc(100%/7)
|
||||
text-align: center
|
||||
align-self: center
|
||||
font-weight: bold
|
||||
@ -271,10 +485,10 @@ label
|
||||
|
||||
&:before
|
||||
content: ""
|
||||
border: 1px solid black
|
||||
border: 1px solid var(--color-highlight-text)
|
||||
border-radius: 3px
|
||||
top: -2.8rem
|
||||
bottom: -1.5rem
|
||||
top: -1rem
|
||||
bottom: -1rem
|
||||
position: absolute
|
||||
width: 100%
|
||||
font-weight: bold
|
||||
@ -283,7 +497,7 @@ label
|
||||
justify-content: center
|
||||
|
||||
&::after
|
||||
content: "PdE"
|
||||
content: ""
|
||||
position: absolute
|
||||
font-size: 1rem
|
||||
top: -2rem
|
||||
@ -291,6 +505,7 @@ label
|
||||
left: 0
|
||||
right: 0
|
||||
line-height: .7rem
|
||||
text-shadow: none
|
||||
|
||||
.splide__arrows
|
||||
position: inherit
|
||||
|
@ -4,62 +4,151 @@ defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
link: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<p>⇠</p>
|
||||
<svg
|
||||
class="color-text"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M22 22L2 22"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M2 11L10.1259 4.49931C11.2216 3.62279 12.7784 3.62279 13.8741 4.49931L22 11"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M15.5 5.5V3.5C15.5 3.22386 15.7239 3 16 3H18.5C18.7761 3 19 3.22386 19 3.5V8.5"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M4 22V9.5"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M20 22V9.5"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M15 22V17C15 15.5858 15 14.8787 14.5607 14.4393C14.1213 14 13.4142 14 12 14C10.5858 14 9.87868 14 9.43934 14.4393C9 14.8787 9 15.5858 9 17V22"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
/>
|
||||
<path
|
||||
d="M14 9.5C14 10.6046 13.1046 11.5 12 11.5C10.8954 11.5 10 10.6046 10 9.5C10 8.39543 10.8954 7.5 12 7.5C13.1046 7.5 14 8.39543 14 9.5Z"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
/>
|
||||
</svg>
|
||||
</router-link>
|
||||
<h1>{{ title }}</h1>
|
||||
<a v-if="link" :href="link">
|
||||
<svg
|
||||
class="color-text"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 17V11"
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<circle
|
||||
cx="1"
|
||||
cy="1"
|
||||
r="1"
|
||||
transform="matrix(1 0 0 -1 11 9)"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
stroke="white"
|
||||
stroke-width="1.5"
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
height: var(--header-size);
|
||||
position: fixed;
|
||||
background: var(--color-green);
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
border-bottom: 1px solid var(--color-text);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
<style lang="sass" scoped>
|
||||
header
|
||||
height: var(--header-size)
|
||||
position: fixed
|
||||
background: var(--color-header-background)
|
||||
color: var(--color-header-text)
|
||||
width: 100%
|
||||
z-index: 1
|
||||
top: 0
|
||||
border-bottom: 1px solid var(--color-header-text)
|
||||
display: flex
|
||||
align-items: center
|
||||
align-content: center
|
||||
|
||||
a {
|
||||
height: 100%;
|
||||
width: var(--header-size);
|
||||
min-width: var(--header-size);
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
border-right: 1px solid var(--color-text);
|
||||
text-decoration: none;
|
||||
}
|
||||
a:first-child
|
||||
border-right: 1px solid var(--color-header-text)
|
||||
a:last-child
|
||||
border-left: 1px solid var(--color-header-text)
|
||||
|
||||
p {
|
||||
margin: 0 auto;
|
||||
font-size: 2rem;
|
||||
color: var(--color-text);
|
||||
}
|
||||
a:hover svg, a:focus svg, a:active svg
|
||||
transform: scale(1.1)
|
||||
|
||||
h1 {
|
||||
margin: 0 1rem;
|
||||
line-height: 0.9;
|
||||
flex: 1;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
a
|
||||
height: 100%
|
||||
width: var(--header-size)
|
||||
min-width: var(--header-size)
|
||||
margin: 0
|
||||
display: flex
|
||||
align-items: center
|
||||
text-align: center
|
||||
align-content: center
|
||||
text-decoration: none
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
p {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
p
|
||||
margin: 0 auto
|
||||
font-size: 2rem
|
||||
color: var(--color-header-text)
|
||||
|
||||
h1
|
||||
margin: 0 1rem
|
||||
line-height: 0.9
|
||||
flex: 1
|
||||
font-size: 1.2rem
|
||||
font-weight: bold
|
||||
text-align: center
|
||||
|
||||
svg
|
||||
width: 2rem
|
||||
margin: 0 auto
|
||||
|
||||
@media (min-height: 1000px)
|
||||
p
|
||||
font-size: 4rem
|
||||
|
||||
h1
|
||||
font-size: 2rem
|
||||
|
||||
svg
|
||||
width: 4rem
|
||||
</style>
|
||||
|
@ -8,7 +8,7 @@ const translationKey = "languages_id";
|
||||
const scores = data.filter((score) => {
|
||||
return (
|
||||
!!score.translations.find(
|
||||
(translation) => translation[translationKey] == store.language
|
||||
(translation) => translation[translationKey] == store.language,
|
||||
) &&
|
||||
score.results.length &&
|
||||
score.questions.length
|
||||
@ -27,51 +27,257 @@ function getTranslation(translations, key) {
|
||||
@click="store.switchTheme"
|
||||
title="Thème de votre système"
|
||||
>
|
||||
🌓
|
||||
<svg
|
||||
class="color-text"
|
||||
version="1.1"
|
||||
id="Icons"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 32 32"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<line
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="16"
|
||||
y1="3"
|
||||
x2="16"
|
||||
y2="29"
|
||||
/>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
d="M16,23c-3.87,0-7-3.13-7-7s3.13-7,7-7"
|
||||
/>
|
||||
<line
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="6.81"
|
||||
y1="6.81"
|
||||
x2="8.93"
|
||||
y2="8.93"
|
||||
/>
|
||||
<line
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="3"
|
||||
y1="16"
|
||||
x2="6"
|
||||
y2="16"
|
||||
/>
|
||||
<line
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="6.81"
|
||||
y1="25.19"
|
||||
x2="8.93"
|
||||
y2="23.07"
|
||||
/>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="#000000"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="10"
|
||||
d="M16,12.55C17.2,10.43,19.48,9,22.09,9c0.16,0,0.31,0.01,0.47,0.02c-1.67,0.88-2.8,2.63-2.8,4.64
|
||||
c0,2.9,2.35,5.25,5.25,5.25c1.6,0,3.03-0.72,3.99-1.85C28.48,20.43,25.59,23,22.09,23c-2.61,0-4.89-1.43-6.09-3.55"
|
||||
/>
|
||||
</svg>
|
||||
</li>
|
||||
<li
|
||||
v-if="store.theme == 'dark'"
|
||||
@click="store.switchTheme"
|
||||
title="Thème sombre"
|
||||
>
|
||||
🌑
|
||||
<svg
|
||||
class="color-text"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill="white"
|
||||
d="M21.0672 11.8568L20.4253 11.469L21.0672 11.8568ZM12.1432 2.93276L11.7553 2.29085V2.29085L12.1432 2.93276ZM21.25 12C21.25 17.1086 17.1086 21.25 12 21.25V22.75C17.9371 22.75 22.75 17.9371 22.75 12H21.25ZM12 21.25C6.89137 21.25 2.75 17.1086 2.75 12H1.25C1.25 17.9371 6.06294 22.75 12 22.75V21.25ZM2.75 12C2.75 6.89137 6.89137 2.75 12 2.75V1.25C6.06294 1.25 1.25 6.06294 1.25 12H2.75ZM15.5 14.25C12.3244 14.25 9.75 11.6756 9.75 8.5H8.25C8.25 12.5041 11.4959 15.75 15.5 15.75V14.25ZM20.4253 11.469C19.4172 13.1373 17.5882 14.25 15.5 14.25V15.75C18.1349 15.75 20.4407 14.3439 21.7092 12.2447L20.4253 11.469ZM9.75 8.5C9.75 6.41182 10.8627 4.5828 12.531 3.57467L11.7553 2.29085C9.65609 3.5593 8.25 5.86509 8.25 8.5H9.75ZM12 2.75C11.9115 2.75 11.8077 2.71008 11.7324 2.63168C11.6686 2.56527 11.6538 2.50244 11.6503 2.47703C11.6461 2.44587 11.6482 2.35557 11.7553 2.29085L12.531 3.57467C13.0342 3.27065 13.196 2.71398 13.1368 2.27627C13.0754 1.82126 12.7166 1.25 12 1.25V2.75ZM21.7092 12.2447C21.6444 12.3518 21.5541 12.3539 21.523 12.3497C21.4976 12.3462 21.4347 12.3314 21.3683 12.2676C21.2899 12.1923 21.25 12.0885 21.25 12H22.75C22.75 11.2834 22.1787 10.9246 21.7237 10.8632C21.286 10.804 20.7293 10.9658 20.4253 11.469L21.7092 12.2447Z"
|
||||
/>
|
||||
</svg>
|
||||
</li>
|
||||
<li
|
||||
v-if="store.theme == 'light'"
|
||||
@click="store.switchTheme"
|
||||
title="Thème clair"
|
||||
>
|
||||
🌞
|
||||
<svg
|
||||
class="color-text"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="12" cy="12" r="5" stroke="#1C274C" stroke-width="1.5" />
|
||||
<path
|
||||
d="M12 2V4"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M12 20V22"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M4 12L2 12"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M22 12L20 12"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M19.7778 4.22266L17.5558 6.25424"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M4.22217 4.22266L6.44418 6.25424"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M6.44434 17.5557L4.22211 19.7779"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M19.7778 19.7773L17.5558 17.5551"
|
||||
stroke="#1C274C"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>Scores Ceiba</h1>
|
||||
<ul>
|
||||
<li v-if="store.language == 'fr-FR'" @click="store.switchLanguage">🇫🇷</li>
|
||||
<li v-if="store.language == 'en-US'" @click="store.switchLanguage">🇺🇸</li>
|
||||
<li v-if="store.language == 'fr-FR'" @click="store.switchLanguage">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="flag-icons-fr"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<path fill="#fff" d="M0 0h640v480H0z" />
|
||||
<path fill="#000091" d="M0 0h213.3v480H0z" />
|
||||
<path fill="#e1000f" d="M426.7 0H640v480H426.7z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li v-if="store.language == 'en-US'" @click="store.switchLanguage">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="flag-icons-gb"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<path fill="#012169" d="M0 0h640v480H0z" />
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="m75 0 244 181L562 0h78v62L400 241l240 178v61h-80L320 301 81 480H0v-60l239-178L0 64V0z"
|
||||
/>
|
||||
<path
|
||||
fill="#C8102E"
|
||||
d="m424 281 216 159v40L369 281zm-184 20 6 35L54 480H0zM640 0v3L391 191l2-44L590 0zM0 0l239 176h-60L0 42z"
|
||||
/>
|
||||
<path fill="#FFF" d="M241 0v480h160V0zM0 160v160h640V160z" />
|
||||
<path fill="#C8102E" d="M0 193v96h640v-96zM273 0v480h96V0z" />
|
||||
</svg>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<main>
|
||||
<img src="/homepage.webp" class="homeImage" />
|
||||
<div class="container" v-if="scores">
|
||||
<ul>
|
||||
<li v-for="score in scores" :key="score.id" :id="`score_${score.id}`">
|
||||
<router-link :to="{ name: 'score', params: { id: score.id } }">{{
|
||||
getTranslation(score.translations, "languages_id").title
|
||||
}}</router-link>
|
||||
</li>
|
||||
<template v-for="(score, index) in scores" :key="score.id">
|
||||
<li class="white" v-if="index % 2 === 0">
|
||||
<router-link :to="{ name: 'score', params: { id: score.id } }">
|
||||
<img height="200" :src="`/answers/${score.image}.webp`" />
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{ name: 'score', params: { id: score.id } }"
|
||||
class="link"
|
||||
>{{
|
||||
getTranslation(score.translations, "languages_id").title
|
||||
}}</router-link
|
||||
>
|
||||
</li>
|
||||
<li class="white" v-if="index % 2 !== 0">
|
||||
<router-link :to="{ name: 'score', params: { id: score.id } }">
|
||||
<img height="200" :src="`/answers/${score.image}.webp`" />
|
||||
</router-link>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<p v-if="store.language == 'fr-FR'">
|
||||
Scores & Appli par <a href="https://ceiba-conseil.com">Ceiba</a>
|
||||
</p>
|
||||
<p v-if="store.language == 'en-US'">
|
||||
Scores & App by <a href="https://ceiba-conseil.com">Ceiba</a>
|
||||
</p>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
footer
|
||||
background: var(--color-header-background)
|
||||
text-align: center
|
||||
padding: 1rem
|
||||
color: var(--color-header-text)
|
||||
height: var(--footer-size)
|
||||
display: flex
|
||||
justify-content: space-around
|
||||
align-items: center
|
||||
a
|
||||
color: var(--color-header-text)
|
||||
header
|
||||
height: var(--header-size)
|
||||
overflow: hidden
|
||||
display: flex
|
||||
justify-content: space-around
|
||||
align-items: center
|
||||
border-bottom: 2px solid var(--color-text)
|
||||
background: var(--color-green)
|
||||
border-bottom: 2px solid var(--color-header-text)
|
||||
color: var(--color-header-text)
|
||||
background: var(--color-header-background)
|
||||
|
||||
h1
|
||||
text-align: center
|
||||
@ -83,6 +289,8 @@ header
|
||||
list-style: none
|
||||
text-align: center
|
||||
font-size: 1.5rem
|
||||
width: 1.5rem
|
||||
height: 2rem
|
||||
|
||||
a
|
||||
text-decoration: none
|
||||
@ -90,71 +298,62 @@ header
|
||||
.hidden
|
||||
display: none
|
||||
|
||||
svg
|
||||
height: 32px
|
||||
width: 32px
|
||||
|
||||
main
|
||||
width: 100%
|
||||
height: calc(100% - var(--header-size))
|
||||
padding: 1rem
|
||||
min-height: calc(100% - var(--header-size) - var(--footer-size))
|
||||
background-color: var(--color-background)
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
text-align: center
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: space-evenly
|
||||
|
||||
.homeImage
|
||||
height: 30vh
|
||||
width: 100%
|
||||
max-width: 600px
|
||||
object-fit: contain
|
||||
margin: 1rem auto 0
|
||||
|
||||
.container
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
overflow: hidden
|
||||
background-color: var(--color-highlight)
|
||||
|
||||
.container
|
||||
position: relative
|
||||
width: 100%
|
||||
max-width: 440px
|
||||
max-height: 100%
|
||||
padding-top: calc(100% / (724 / 1136))
|
||||
|
||||
@media only screen and (min-width: 472px)
|
||||
padding-top: 0
|
||||
width: 440px
|
||||
height: calc(440px * 1136 / 724)
|
||||
padding: 1rem
|
||||
|
||||
ul
|
||||
margin: 0
|
||||
padding: 0
|
||||
list-style: none
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
bottom: 0
|
||||
right: 0
|
||||
|
||||
background-image: url(/arbre.webp)
|
||||
background-position: center
|
||||
background-repeat: no-repeat
|
||||
background-size: contain
|
||||
|
||||
border-radius: 10px
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
justify-content: center
|
||||
max-width: 404px
|
||||
border: 1px solid var(--color-green)
|
||||
|
||||
li
|
||||
display: none
|
||||
height: 202px
|
||||
width: 202px
|
||||
max-width: 50%
|
||||
border: 1px solid var(--color-green)
|
||||
|
||||
background: rgba(0, 0, 0, .5)
|
||||
border-radius: 10px
|
||||
position: absolute
|
||||
border: 2px solid var(--color-text)
|
||||
img
|
||||
max-width: 100%
|
||||
object-fit: contain
|
||||
|
||||
&#score_1
|
||||
display: flex
|
||||
top: 40%
|
||||
bottom: 35%
|
||||
left: 20%
|
||||
right: 20%
|
||||
.white
|
||||
background: white
|
||||
|
||||
&#score_6
|
||||
display: flex
|
||||
top: 72%
|
||||
bottom: 5%
|
||||
left: 6%
|
||||
right: 6%
|
||||
|
||||
a
|
||||
color: var(--color-text)
|
||||
a.link
|
||||
font-size: 2rem
|
||||
line-height: 2rem
|
||||
color: var(--color-green)
|
||||
display: block
|
||||
width: 100%
|
||||
height: 100%
|
||||
@ -162,4 +361,6 @@ main
|
||||
align-items: center
|
||||
justify-content: center
|
||||
text-align: center
|
||||
padding: 1rem
|
||||
text-decoration: none
|
||||
</style>
|
||||
|
@ -1,10 +1,16 @@
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import piniaPersist from "pinia-plugin-persist";
|
||||
import { registerSW } from "virtual:pwa-register";
|
||||
|
||||
import App from "@/App.vue";
|
||||
import router from "@/router";
|
||||
|
||||
if ("serviceWorker" in navigator) {
|
||||
// && !/localhost/.test(window.location)) {
|
||||
registerSW();
|
||||
}
|
||||
|
||||
const app = createApp(App);
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPersist);
|
||||
|
@ -1,11 +1,55 @@
|
||||
import { fileURLToPath, URL } from "url";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
|
||||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
// publicDir: 'public',
|
||||
// includeAssets: ['public/answers/*.web'],
|
||||
plugins: [
|
||||
vue(),
|
||||
VitePWA({
|
||||
name: "My First Progressive Web app",
|
||||
short_name: "First PWA",
|
||||
theme_color: "#eb5252",
|
||||
background_color: "#000000",
|
||||
registerType: "autoUpdate",
|
||||
injectRegister: "auto",
|
||||
// add this to cache all the imports
|
||||
workbox: {
|
||||
globPatterns: ["**/*"],
|
||||
},
|
||||
// add this to cache all the
|
||||
// static assets in the public folder
|
||||
includeAssets: ["**/*"],
|
||||
useCredentials: true,
|
||||
manifest: {
|
||||
theme_color: "#eb5252",
|
||||
orientation: "portrait",
|
||||
display: "fullscreen",
|
||||
scope: "/",
|
||||
icons: [
|
||||
{
|
||||
src: "/images/pwa-icon-256.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
purpose: "any maskable",
|
||||
},
|
||||
{
|
||||
src: "/images/pwa-icon-512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any maskable",
|
||||
},
|
||||
],
|
||||
},
|
||||
devOptions: {
|
||||
enabled: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||
|
Reference in New Issue
Block a user