feat: Mise à jour du deisgn de l'application
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Simon 2023-04-27 22:31:59 +02:00
parent 58a6da1d94
commit 939055a64d
16 changed files with 632 additions and 83 deletions

3
.gitignore vendored
View File

@ -30,3 +30,6 @@ coverage
# app
src/data.json
public/answers
public/homepage.webp
public/logo.png
public/favicon/*.png

View File

@ -4,36 +4,55 @@ Vous trouverez ici le code source de l'application de Scores de [Ceiba Conseil](
## 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 automatique 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
L'application a été développé 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.
### Recommendation pour votre environnement de 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).
## Customize configuration
Une configuration spécifique à Vite peut être mise en place, voir [la référence](https://vitejs.dev/config/).
See [Vite Configuration Reference](https://vitejs.dev/config/).
### Commandes
## Project Setup
Installation des dépendances
```sh
npm install
```
### Compile and Hot-Reload for Development
Compilation avec du Hot-Reload (Rechargement à chaud) pour le développement
```sh
npm run dev
```
### Compile and Minify for Production
Compilation and minification pour la production
```sh
npm run build
```
### Lint with [ESLint](https://eslint.org/)
Les règles de mise en forme sont assuré par [ESLint](https://eslint.org/)
```sh
npm run lint
```
## Logiciels utilisés
RésiLien met en place des outils open source eprouvé dans le temps et dont les communautés sont assez grande pour permettre une perenité de ses projets.
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

View File

@ -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>

83
package-lock.json generated
View File

@ -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",

View File

@ -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

View 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>

View 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"
}
]
}

91
public/test.html Normal file
View 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>

View File

@ -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

View File

@ -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);
}

View File

@ -93,6 +93,7 @@ function slideMove(splide, newIndex) {
width: 1.6rem
.splide__pagination
bottom: -1.5em
display: none
.splide__pagination__page
width: .7rem
height: .7rem
@ -108,7 +109,7 @@ legend
text-align: center
font-size: 1.4rem
line-height: 2rem
margin: 1rem
font-weight: bold
.choices
list-style-type: none
@ -116,12 +117,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 +134,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 +169,9 @@ legend
max-width: 100%
min-width: 280px
@media (max-height: 600px)
margin: 1rem auto
h2
font-size: 2rem

View File

@ -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

View File

@ -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>

View File

@ -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>