feat: Mise à jour du design de l'application
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
58a6da1d94
commit
9d3e144748
|
@ -30,3 +30,6 @@ coverage
|
|||
# app
|
||||
src/data.json
|
||||
public/answers
|
||||
public/homepage.webp
|
||||
public/logo.png
|
||||
public/favicon/*.png
|
||||
|
|
49
README.md
49
README.md
|
@ -2,38 +2,39 @@
|
|||
|
||||
Vous trouverez ici le code source de l'application de Scores de [Ceiba Conseil](https://www.ceiba-conseil.com/).
|
||||
|
||||
## Information
|
||||
## Information
|
||||
|
||||
- Les emojis ont été pris depuis le site https://twemoji-cheatsheet.vercel.app/
|
||||
- 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
|
||||
|
||||
## Recommended IDE Setup
|
||||
## Développement
|
||||
|
||||
[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).
|
||||
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.
|
||||
|
||||
## Customize configuration
|
||||
### Recommandation pour votre environnement de développement
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
_[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).
|
||||
|
||||
## Project Setup
|
||||
Une configuration spécifique à _Vite_ peut être mise en place, voir [la référence](https://vitejs.dev/config/).
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
### Commandes
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
- 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 dev
|
||||
```
|
||||
## Logiciels utilisés
|
||||
|
||||
### Compile and Minify for Production
|
||||
_RésiLien_ met en place des outils open source eprouvé dans le temps et dont les communautés sont assez grandes pour permettre une perenité de ses projets.
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```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
|
||||
|
|
17
index.html
17
index.html
|
@ -2,7 +2,22 @@
|
|||
<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">
|
||||
<link rel="manifest" href="/favicon/manifest.json">
|
||||
<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>
|
||||
</head>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@splidejs/vue-splide": "^0.5.18",
|
||||
"html2canvas": "^1.4.1",
|
||||
"pinia": "^2.0.11",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"sass": "^1.49.9",
|
||||
|
@ -542,6 +543,14 @@
|
|||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
|
@ -844,6 +853,14 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
|
@ -1779,6 +1796,18 @@
|
|||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||
},
|
||||
"node_modules/html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"dependencies": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -3059,6 +3088,14 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
|
@ -3124,6 +3161,14 @@
|
|||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"node_modules/utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||
|
@ -3814,6 +3859,11 @@
|
|||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
|
@ -4019,6 +4069,14 @@
|
|||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"requires": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
|
@ -4622,6 +4680,15 @@
|
|||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||
},
|
||||
"html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"requires": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -5490,6 +5557,14 @@
|
|||
"terser": "^5.7.2"
|
||||
}
|
||||
},
|
||||
"text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"requires": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
|
@ -5540,6 +5615,14 @@
|
|||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@splidejs/vue-splide": "^0.5.18",
|
||||
"html2canvas": "^1.4.1",
|
||||
"pinia": "^2.0.11",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"sass": "^1.49.9",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
|
@ -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>
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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,7 @@ async function fetchAsset(uuid) {
|
|||
return fetch(url);
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
async function fetchScoresData() {
|
||||
const fields = [
|
||||
"*",
|
||||
"translations.*",
|
||||
|
@ -72,18 +72,7 @@ async function fetchData() {
|
|||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,4 +81,231 @@ 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 fetchScoresData();
|
||||
}
|
||||
|
||||
fetchData();
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 626 KiB |
|
@ -8,6 +8,7 @@
|
|||
|
||||
--header-size-small: 64px;
|
||||
--header-size-big: 128px;
|
||||
--header-size: var(--header-size-small);
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
|
@ -19,7 +20,6 @@
|
|||
--color-highlight-background: var(--color-green);
|
||||
--color-highlight-text: var(--color-white);
|
||||
--color-highlight-text-invert: var(--color-black);
|
||||
--header-size: var(--header-size-small)
|
||||
}
|
||||
|
||||
body.theme-dark {
|
||||
|
@ -44,7 +44,7 @@ body.theme-dark {
|
|||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@media (min-height: 800px) {
|
||||
:root {
|
||||
--header-size: var(--header-size-big);
|
||||
}
|
||||
|
@ -80,3 +80,17 @@ body {
|
|||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
|
|
@ -41,11 +41,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>
|
||||
|
@ -77,9 +73,39 @@ function slideMove(splide, newIndex) {
|
|||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
.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)
|
||||
|
@ -93,6 +119,7 @@ function slideMove(splide, newIndex) {
|
|||
width: 1.6rem
|
||||
.splide__pagination
|
||||
bottom: -1.5em
|
||||
display: none
|
||||
.splide__pagination__page
|
||||
width: .7rem
|
||||
height: .7rem
|
||||
|
@ -108,7 +135,7 @@ legend
|
|||
text-align: center
|
||||
font-size: 1.4rem
|
||||
line-height: 2rem
|
||||
margin: 1rem
|
||||
font-weight: bold
|
||||
|
||||
.choices
|
||||
list-style-type: none
|
||||
|
@ -116,12 +143,15 @@ legend
|
|||
display: inline-block
|
||||
padding-left: 0
|
||||
|
||||
label
|
||||
cursor: pointer
|
||||
|
||||
input[type=radio]
|
||||
display: none
|
||||
|
||||
& + label
|
||||
position: relative
|
||||
padding-left: 2rem
|
||||
padding: .2rem .2rem .2rem 2rem
|
||||
& + label::before,
|
||||
& + label::after
|
||||
display: block
|
||||
|
@ -130,20 +160,22 @@ legend
|
|||
content:''
|
||||
border-radius: 1rem
|
||||
& + label::before
|
||||
bottom: 0
|
||||
bottom: .3rem
|
||||
left: 0
|
||||
background-color: var(--color-green)
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
& + label::after
|
||||
bottom: 3px
|
||||
bottom: calc(3px + .3rem)
|
||||
left: 3px
|
||||
width: calc(1rem - 6px)
|
||||
height: calc(1rem - 6px)
|
||||
&:checked + label
|
||||
text-shadow: -0.06ex 0 0 currentColor, 0.06ex 0 0 currentColor
|
||||
&:checked + label::before
|
||||
background-color: white
|
||||
&:checked + label::after
|
||||
background-color: var(--color-green)
|
||||
&:checked + label::after
|
||||
background-color: white
|
||||
|
||||
.main
|
||||
height: 100%
|
||||
|
@ -163,6 +195,9 @@ legend
|
|||
max-width: 100%
|
||||
min-width: 280px
|
||||
|
||||
@media (max-height: 600px)
|
||||
margin: 1rem auto
|
||||
|
||||
h2
|
||||
font-size: 2rem
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Splide, SplideSlide } from "@splidejs/vue-splide";
|
|||
import Question from "./Question.vue";
|
||||
import "@splidejs/splide/dist/css/splide.min.css";
|
||||
import ScoreHeader from "./ScoreHeader.vue";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
@ -110,6 +111,16 @@ function nextQuestion() {
|
|||
console.log(slides);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
async function share() {
|
||||
console.log(document.querySelector(".latest"));
|
||||
const canvas = await html2canvas(document.querySelector("html"));
|
||||
let anchor = document.createElement("a");
|
||||
anchor.download = "download.png";
|
||||
anchor.href = canvas.toDataURL("image/png");
|
||||
anchor.click();
|
||||
anchor.remove();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -135,7 +146,7 @@ function nextQuestion() {
|
|||
@nextQuestion="nextQuestion"
|
||||
/>
|
||||
</SplideSlide>
|
||||
<SplideSlide class="latest" id="details">
|
||||
<SplideSlide class="latest">
|
||||
<template v-if="displayScoreResult && result">
|
||||
<div>
|
||||
<h2 class="center">Probabilité d'échec</h2>
|
||||
|
@ -162,7 +173,7 @@ function nextQuestion() {
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button>Partager</button>
|
||||
<button @click="() => share()">Partager</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -251,17 +262,23 @@ label
|
|||
line-height: 2rem
|
||||
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
|
||||
font-size: 1.1rem
|
||||
text-align: left !important
|
||||
font-family: serif
|
||||
font-size: .9rem
|
||||
line-height: normal
|
||||
background: var(--color-highlight-background)
|
||||
border: 1px solid var(--color-highlight-text)
|
||||
background: var(--color-text)
|
||||
margin: 1rem
|
||||
padding: 1rem
|
||||
|
||||
.gradient
|
||||
|
|
|
@ -10,57 +10,94 @@ defineProps({
|
|||
<template>
|
||||
<header>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<p>⇠</p>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
||||
<path
|
||||
fill="#5C913B"
|
||||
d="M36 33.5c0 .828-.672 1.5-1.5 1.5h-33C.672 35 0 34.328 0 33.5S.672 32 1.5 32h33c.828 0 1.5.672 1.5 1.5z"
|
||||
/>
|
||||
<path
|
||||
fill="#A0041E"
|
||||
d="M12.344 14.702h-2c-.276 0-.5-.224-.5-.5v-7c0-.276.224-.5.5-.5h2c.276 0 .5.224.5.5v7c0 .276-.224.5-.5.5z"
|
||||
/>
|
||||
<path
|
||||
fill="#FFCC4D"
|
||||
d="M5.942 32c-.137-4.657-.506-8-.942-8-.435 0-.804 3.343-.941 8h1.883z"
|
||||
/>
|
||||
<path
|
||||
fill="#77B255"
|
||||
d="M10 18.731C10 24.306 7.762 26 5 26c-2.761 0-5-1.694-5-7.269C0 13.154 4 5 5 5s5 8.154 5 13.731z"
|
||||
/>
|
||||
<path fill="#FFE8B6" d="M8 16L21 3l13 13v16H8z" />
|
||||
<path fill="#FFCC4D" d="M21 16h1v16h-1z" />
|
||||
<path
|
||||
fill="#66757F"
|
||||
d="M34 17c-.256 0-.512-.098-.707-.293L21 4.414 8.707 16.707c-.391.391-1.023.391-1.414 0s-.391-1.023 0-1.414l13-13c.391-.391 1.023-.391 1.414 0l13 13c.391.391.391 1.023 0 1.414-.195.195-.451.293-.707.293z"
|
||||
/>
|
||||
<path
|
||||
fill="#66757F"
|
||||
d="M21 17c-.256 0-.512-.098-.707-.293-.391-.391-.391-1.023 0-1.414l6.5-6.5c.391-.391 1.023-.391 1.414 0s.391 1.023 0 1.414l-6.5 6.5c-.195.195-.451.293-.707.293z"
|
||||
/>
|
||||
<path fill="#C1694F" d="M13 26h4v6h-4z" />
|
||||
<path fill="#55ACEE" d="M13 17h4v4h-4zm12.5 0h4v4h-4zm0 9h4v4h-4z" />
|
||||
<path
|
||||
fill="#77B255"
|
||||
d="M10.625 29.991c0 1.613-.858 2.103-1.917 2.103-1.058 0-1.917-.49-1.917-2.103 0-1.613 1.533-3.973 1.917-3.973s1.917 2.359 1.917 3.973zm25.25 0c0 1.613-.858 2.103-1.917 2.103-1.058 0-1.917-.49-1.917-2.103 0-1.613 1.533-3.973 1.917-3.973.384 0 1.917 2.359 1.917 3.973z"
|
||||
/>
|
||||
</svg>
|
||||
</router-link>
|
||||
<h1>{{ title }}</h1>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style 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;
|
||||
}
|
||||
<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-header-text);
|
||||
text-decoration: none;
|
||||
}
|
||||
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-header-text)
|
||||
text-decoration: none
|
||||
|
||||
p {
|
||||
margin: 0 auto;
|
||||
font-size: 2rem;
|
||||
color: var(--color-header-text);
|
||||
}
|
||||
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;
|
||||
}
|
||||
h1
|
||||
margin: 0 1rem
|
||||
line-height: 0.9
|
||||
flex: 1
|
||||
font-size: 1.2rem
|
||||
font-weight: bold
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
p {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
svg
|
||||
width: 2rem
|
||||
margin: 0 auto
|
||||
|
||||
@media (min-height: 800px)
|
||||
p
|
||||
font-size: 4rem
|
||||
|
||||
h1
|
||||
font-size: 2rem
|
||||
|
||||
svg
|
||||
width: 4rem
|
||||
</style>
|
||||
|
|
|
@ -123,6 +123,7 @@ function getTranslation(translations, key) {
|
|||
</ul>
|
||||
</header>
|
||||
<main>
|
||||
<img src="/homepage.webp" class="homeImage" />
|
||||
<div class="container" v-if="scores">
|
||||
<ul>
|
||||
<template v-for="(score, index) in scores" :key="score.id">
|
||||
|
@ -177,14 +178,25 @@ header
|
|||
main
|
||||
width: 100%
|
||||
height: calc(100% - var(--header-size))
|
||||
padding: 1rem
|
||||
background-color: var(--color-background)
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
text-align: center
|
||||
|
||||
.homeImage
|
||||
height: 30vh
|
||||
width: 100%
|
||||
max-width: 600px
|
||||
object-fit: contain
|
||||
margin: 0 auto
|
||||
|
||||
.container
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
overflow: hidden
|
||||
background-color: var(--color-background)
|
||||
padding: 1rem
|
||||
|
||||
.container
|
||||
ul
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
@ -193,6 +205,7 @@ main
|
|||
flex-wrap: wrap
|
||||
justify-content: center
|
||||
max-width: 404px
|
||||
border: 1px solid var(--color-green)
|
||||
|
||||
li
|
||||
height: 202px
|
||||
|
@ -206,6 +219,7 @@ main
|
|||
|
||||
a
|
||||
font-size: 2rem
|
||||
line-height: 2rem
|
||||
color: var(--color-green)
|
||||
display: block
|
||||
width: 100%
|
||||
|
@ -215,4 +229,5 @@ main
|
|||
justify-content: center
|
||||
text-align: center
|
||||
padding: 1rem
|
||||
text-decoration: none
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue