Automated Release v1.1.0
Please find changes in CHANGELOG.md file
|
@ -0,0 +1,27 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [1.0.13] - 2020-04-06
|
||||||
|
### Added
|
||||||
|
- first public release
|
||||||
|
## [1.1.0] - 2020-04-08
|
||||||
|
### Added
|
||||||
|
- (#21, #23, #25, #26, #27, #28, #29) :wheelchair: improve A11Y support
|
||||||
|
- adds github links in footer
|
||||||
|
- (#19) clear localstorage
|
||||||
|
- prevent sending personal data
|
||||||
|
- 💚 Publish html as workflow asset and code in public repository
|
||||||
|
- Add sitemap and tell robots.txt to scan the sitemap
|
||||||
|
- Add Changelog
|
||||||
|
### Changes
|
||||||
|
- (#18) 📝 Update header for reasons section
|
||||||
|
- (#3) ✏ Replace codiv by covid in package.json, README
|
||||||
|
- changes start target
|
||||||
|
- (#1) 🐛 Autocomplete birthday field only on keyup, not when deleting
|
||||||
|
- (#1) 🎨 Improve regex control pattern for birhtday
|
||||||
|
- :recycle: Move check update code to dedicated file
|
||||||
|
- :recycle: Move dom utils in dedicated file
|
||||||
|
- :sparkles: Notify user about newer version
|
||||||
|
- :sparkles: Add cache with service workers
|
||||||
|
- :recycle: Cleanup directory structure
|
||||||
|
- :heavy_plus_sign: Avoid using env specific syntax in npm scripts
|
||||||
|
- changes PWA display
|
|
@ -5,8 +5,8 @@
|
||||||
### Installer le projet
|
### Installer le projet
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ git clone https://github.com/lab-mi/deplacement-codiv-19.git
|
$ git clone https://github.com/lab-mi/deplacement-covid-19.git
|
||||||
$ cd deplacement-codiv-19
|
$ cd deplacement-covid-19
|
||||||
$ npm i
|
$ npm i
|
||||||
$ npm start
|
$ npm start
|
||||||
```
|
```
|
||||||
|
@ -23,7 +23,8 @@ Le code à déployer sera dans le dossier `dist`
|
||||||
|
|
||||||
Ce projet a été réalisé à partir d'un fork du dépôt [covid-19-certificate](https://github.com/nesk/covid-19-certificate) de [Johann Pardanaud](https://github.com/nesk).
|
Ce projet a été réalisé à partir d'un fork du dépôt [covid-19-certificate](https://github.com/nesk/covid-19-certificate) de [Johann Pardanaud](https://github.com/nesk).
|
||||||
|
|
||||||
Les projets open source suivants ont été utilisés pour le développement de ce service :
|
Les projets open source suivants ont été utilisés pour le développement de ce
|
||||||
|
service :
|
||||||
|
|
||||||
- [PDF-LIB](https://pdf-lib.js.org/)
|
- [PDF-LIB](https://pdf-lib.js.org/)
|
||||||
- [qrcode](https://github.com/soldair/node-qrcode)
|
- [qrcode](https://github.com/soldair/node-qrcode)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"short_name": "",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "android-chrome-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "android-chrome-512x512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"theme_color": "#ffffff",
|
|
||||||
"background_color": "#ffffff",
|
|
||||||
"display": "standalone"
|
|
||||||
}
|
|
40
package.json
|
@ -5,14 +5,18 @@
|
||||||
"main": "certificate.js",
|
"main": "certificate.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint ./*.js",
|
"lint": "eslint ./*.js",
|
||||||
"start": "VERSION=${VERSION:-localversion} parcel index.html robots.txt",
|
"start": "cross-env VERSION=${VERSION:-localversion} parcel --public-url ${PUBLIC_URL:-/deplacement-covid-19} ./src/index.html",
|
||||||
"prebuild": "npm run lint && rimraf dist",
|
"clean:dist": "rimraf dist",
|
||||||
"build": "PUBLIC_URL=${PUBLIC_URL:-/deplacement-covid-19} ; parcel build --public-url ${PUBLIC_URL} index.html robots.txt",
|
"prebuild": "run-s lint clean:dist",
|
||||||
"postbuild": "PUBLIC_URL=${PUBLIC_URL:-/deplacement-covid-19} react-snap"
|
"build": "parcel build --public-url ${PUBLIC_URL:-/deplacement-covid-19} ./src/index.html ./src/robots.txt ./src/sitemap.xml",
|
||||||
|
"postbuild": "PUBLIC_URL=${PUBLIC_URL:-/deplacement-covid-19} react-snap",
|
||||||
|
"preserve": "npm run build",
|
||||||
|
"serve": "serve dist",
|
||||||
|
"serve:dist": "serve dist"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/lab-mi/deplacement-codiv-19"
|
"url": "git+https://github.com/lab-mi/deplacement-covid-19"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
|
@ -24,21 +28,28 @@
|
||||||
"@babel/core": "^7.9.0",
|
"@babel/core": "^7.9.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.9.0",
|
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
|
"copy-and-watch": "^0.1.4",
|
||||||
|
"cross-env": "^7.0.2",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-config-standard": "^14.1.1",
|
"eslint-config-standard": "^14.1.1",
|
||||||
"eslint-plugin-import": "^2.20.1",
|
"eslint-plugin-import": "^2.20.2",
|
||||||
"eslint-plugin-node": "^11.0.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^4.2.1",
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
"eslint-plugin-standard": "^4.0.1",
|
"eslint-plugin-standard": "^4.0.1",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
"parcel-bundler": "^1.12.4",
|
"parcel-bundler": "^1.12.4",
|
||||||
|
"parcel-plugin-sw-cache": "^0.3.1",
|
||||||
"postcss-current-selector": "0.0.3",
|
"postcss-current-selector": "0.0.3",
|
||||||
"postcss-nested": "^4.2.1",
|
"postcss-nested": "^4.2.1",
|
||||||
"postcss-nested-ancestors": "^2.0.0",
|
"postcss-nested-ancestors": "^2.0.0",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-preset-env": "^6.7.0",
|
||||||
"react-snap": "^1.23.0",
|
"react-snap": "^1.23.0",
|
||||||
"rimraf": "^3.0.2"
|
"rimraf": "^3.0.2",
|
||||||
|
"serve": "^11.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||||
"bootstrap": "^4.4.1",
|
"bootstrap": "^4.4.1",
|
||||||
"pdf-lib": "^1.4.1",
|
"pdf-lib": "^1.4.1",
|
||||||
"qrcode": "^1.4.4"
|
"qrcode": "^1.4.4"
|
||||||
|
@ -52,5 +63,16 @@
|
||||||
"collapseWhitespace": false,
|
"collapseWhitespace": false,
|
||||||
"removeComments": false
|
"removeComments": false
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"cache": {
|
||||||
|
"globPatterns": [
|
||||||
|
"**/*.{html,js,css,jpg,png,pdf,svg,eot,ttf,woff,woff2}"
|
||||||
|
],
|
||||||
|
"disablePlugin": false,
|
||||||
|
"inDev": true,
|
||||||
|
"strategy": "default",
|
||||||
|
"clearDist": false,
|
||||||
|
"templatedURLs": {
|
||||||
|
"/": ["index.html"]
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
User-agent: *
|
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
@ -1,13 +1,20 @@
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||||
|
|
||||||
|
import './main.css'
|
||||||
|
|
||||||
import { PDFDocument, StandardFonts } from 'pdf-lib'
|
import { PDFDocument, StandardFonts } from 'pdf-lib'
|
||||||
import QRCode from 'qrcode'
|
import QRCode from 'qrcode'
|
||||||
|
import { library, dom } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
import { faEye, faFilePdf } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
import './check-updates'
|
||||||
|
import { $, $$ } from './dom-utils'
|
||||||
import pdfBase from './certificate.pdf'
|
import pdfBase from './certificate.pdf'
|
||||||
import './main.css'
|
|
||||||
|
|
||||||
const $ = (...args) => document.querySelector(...args)
|
library.add(faEye, faFilePdf)
|
||||||
const $$ = (...args) => [...document.querySelectorAll(...args)]
|
|
||||||
|
dom.watch()
|
||||||
|
|
||||||
var year, month, day
|
var year, month, day
|
||||||
|
|
||||||
const generateQR = async text => {
|
const generateQR = async text => {
|
||||||
|
@ -209,24 +216,34 @@ function isFacebookBrowser () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFacebookBrowser()) {
|
if (isFacebookBrowser()) {
|
||||||
|
$('#alert-facebook').value = 'ATTENTION !! Vous utilisez actuellement le navigateur Facebook, ce générateur ne fonctionne pas correctement au sein de ce navigateur ! Merci d\'ouvrir Chrome sur Android ou bien Safari sur iOS.'
|
||||||
$('#alert-facebook').classList.remove('d-none')
|
$('#alert-facebook').classList.remove('d-none')
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSlash () {
|
function addSlash () {
|
||||||
this.value = this.value.replace(/^(\d{2})$/g, '$1/')
|
$('#field-birthday').value = $('#field-birthday').value.replace(/^(\d{2})$/g, '$1/')
|
||||||
this.value = this.value.replace(/^(\d{2})\/(\d{2})$/g, '$1/$2/')
|
$('#field-birthday').value = $('#field-birthday').value.replace(/^(\d{2})\/(\d{2})$/g, '$1/$2/')
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#field-birthday').addEventListener('keyup', addSlash)
|
$('#field-birthday').onkeyup = function () {
|
||||||
|
const key = event.keyCode || event.charCode
|
||||||
|
if (key === 8 || key === 46) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
addSlash()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const snackbar = $('#snackbar')
|
const snackbar = $('#snackbar')
|
||||||
|
|
||||||
$('#form-profile').addEventListener('submit', async event => {
|
$('#generate-btn').addEventListener('click', async event => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
saveProfile()
|
saveProfile()
|
||||||
const reasons = getAndSaveReasons()
|
const reasons = getAndSaveReasons()
|
||||||
const pdfBlob = await generatePdf(getProfile(), reasons)
|
const pdfBlob = await generatePdf(getProfile(), reasons)
|
||||||
|
localStorage.clear()
|
||||||
downloadBlob(pdfBlob, 'attestation.pdf')
|
downloadBlob(pdfBlob, 'attestation.pdf')
|
||||||
|
|
||||||
snackbar.classList.remove('d-none')
|
snackbar.classList.remove('d-none')
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { $ } from './dom-utils'
|
||||||
|
|
||||||
|
// Ce fichier est généré au build par le plugin parcel-plugin-sw-cache
|
||||||
|
const swName = './sw.js'
|
||||||
|
window.isUpdateAvailable = new Promise(function (resolve, reject) {
|
||||||
|
// lazy way of disabling service workers while developing
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.register(swName)
|
||||||
|
.then(registration => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
switch (installingWorker.state) {
|
||||||
|
case 'installed':
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// new update available
|
||||||
|
resolve(true)
|
||||||
|
} else {
|
||||||
|
// no update available
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error('[SW ERROR]', err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.isUpdateAvailable.then(isAvailable => {
|
||||||
|
$('#reload-btn').addEventListener('click', () => window.location.reload())
|
||||||
|
$('#update-alert').classList.remove('d-none')
|
||||||
|
})
|
|
@ -40,7 +40,10 @@
|
||||||
déplacement ne font l’objet d’aucune collecte par le ministère
|
déplacement ne font l’objet d’aucune collecte par le ministère
|
||||||
de l’Intérieur. Ces données personnelles<sup>1</sup> sont
|
de l’Intérieur. Ces données personnelles<sup>1</sup> sont
|
||||||
exclusivement stockées dans le terminal (ordinateur, tablette,
|
exclusivement stockées dans le terminal (ordinateur, tablette,
|
||||||
smartphone) utilisé pour générer l’attestation.
|
smartphone) utilisé pour générer l’attestation. Le code source
|
||||||
|
de ce gérérateur d'attestation est ouvert. Il peut être consulté
|
||||||
|
sur <a href="https://github.com/LAB-MI/deplacement-covid-19">
|
||||||
|
https://github.com/LAB-MI/deplacement-covid-19</a>.
|
||||||
</p>
|
</p>
|
||||||
<em>1 - Prénom, Nom, Date de naissance, Lieu de naissance, Adresse,
|
<em>1 - Prénom, Nom, Date de naissance, Lieu de naissance, Adresse,
|
||||||
Code postal, Ville.</em>
|
Code postal, Ville.</em>
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const $ = (...args) => document.querySelector(...args)
|
||||||
|
export const $$ = (...args) => [...document.querySelectorAll(...args)]
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 613 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "Générateur d'attestation de déplacement dérogatoire",
|
||||||
|
"short_name": "Déplacement covid-19",
|
||||||
|
"desctiption": "L'application officielle du gouvernement pour la génération d'attestation de déplacement dérogatoire dématérialisée.",
|
||||||
|
"categories": ["government", "health"],
|
||||||
|
"lang": "fr-FR",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"orientation": "portrait-primary",
|
||||||
|
"theme_color": "#ced4da",
|
||||||
|
"background_color": "#000191",
|
||||||
|
"display": "minimal-ui"
|
||||||
|
}
|
|
@ -30,7 +30,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="wrapper">
|
<header class="wrapper">
|
||||||
<img class="logo" src="/MIN_Interieur_RVB.svg" alt="">
|
<img class="logo" src="/MIN_Interieur_RVB.svg" alt="Ministère de l'intérieur. Liberté, égalité, fraternité.">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="flex flex-wrap">
|
<h1 class="flex flex-wrap">
|
||||||
<span class="covid-title">
|
<span class="covid-title">
|
||||||
|
@ -48,10 +48,13 @@
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<p class="alert alert-danger d-none" role="alert" id="alert-facebook"></p>
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
<form id="form-profile">
|
<form id="form-profile" accept-charset="UTF-8">
|
||||||
<h2 class="titre-2">Remplissez en ligne votre attestation numérique :</h2>
|
<h2 class="titre-2">Remplissez en ligne votre attestation numérique :</h2>
|
||||||
|
<p class="text-alert">Tous les champs sont obligatoires.</p>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-firstname" id="field-firstname-label">Prénom</label>
|
<label for="field-firstname" id="field-firstname-label">Prénom</label>
|
||||||
|
@ -63,11 +66,10 @@
|
||||||
name="firstname"
|
name="firstname"
|
||||||
autocomplete="given-name"
|
autocomplete="given-name"
|
||||||
placeholder="Jean"
|
placeholder="Jean"
|
||||||
aria-labelledby="field-firstname-label"
|
|
||||||
required
|
required
|
||||||
autofocus
|
autofocus
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,11 +84,10 @@
|
||||||
name="lastname"
|
name="lastname"
|
||||||
autocomplete="family-name"
|
autocomplete="family-name"
|
||||||
placeholder="Dupont"
|
placeholder="Dupont"
|
||||||
aria-labelledby="field-lastname-label"
|
|
||||||
required
|
required
|
||||||
autofocus
|
autofocus
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,6 +97,7 @@
|
||||||
<div class="input-group align-items-center">
|
<div class="input-group align-items-center">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
pattern="^([0][1-9]|[1-2][0-9]|30|31)/([0][1-9]|10|11|12)/(19[0-9][0-9]|20[0-1][0-9]|2020)"
|
||||||
inputmode="numeric"
|
inputmode="numeric"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="field-birthday"
|
id="field-birthday"
|
||||||
|
@ -103,10 +105,9 @@
|
||||||
autocomplete="bday"
|
autocomplete="bday"
|
||||||
placeholder="01/01/1970"
|
placeholder="01/01/1970"
|
||||||
maxlength="10"
|
maxlength="10"
|
||||||
aria-labelledby="field-birthday-label"
|
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -119,11 +120,10 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="field-lieunaissance"
|
id="field-lieunaissance"
|
||||||
name="lieunaissance"
|
name="lieunaissance"
|
||||||
aria-labelledby="field-lieunaissance-label"
|
|
||||||
placeholder="Lyon"
|
placeholder="Lyon"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -137,11 +137,10 @@
|
||||||
id="field-address"
|
id="field-address"
|
||||||
name="address"
|
name="address"
|
||||||
autocomplete="address-line1"
|
autocomplete="address-line1"
|
||||||
aria-labelledby="field-address-label"
|
|
||||||
placeholder="999 avenue de france"
|
placeholder="999 avenue de france"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -155,11 +154,10 @@
|
||||||
id="field-town"
|
id="field-town"
|
||||||
name="town"
|
name="town"
|
||||||
autocomplete="address-level1"
|
autocomplete="address-level1"
|
||||||
aria-labelledby="field-town-label"
|
|
||||||
placeholder="Paris"
|
placeholder="Paris"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -168,85 +166,91 @@
|
||||||
<label for="field-zipcode" id="field-zipcode-label" >Code Postal</label>
|
<label for="field-zipcode" id="field-zipcode-label" >Code Postal</label>
|
||||||
<div class="input-group align-items-center">
|
<div class="input-group align-items-center">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="text"
|
||||||
|
inputmode="numeric"
|
||||||
|
pattern="[0-9]{5}"
|
||||||
min="00000"
|
min="00000"
|
||||||
max="99999"
|
max="99999"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="field-zipcode"
|
id="field-zipcode"
|
||||||
name="zipcode"
|
name="zipcode"
|
||||||
autocomplete="zipcode"
|
autocomplete="postal-code"
|
||||||
minlength="4"
|
minlength="4"
|
||||||
maxlength="5"
|
maxlength="5"
|
||||||
aria-labelledby="field-zipcode-label"
|
|
||||||
placeholder="75001"
|
placeholder="75001"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="exemple"></p>
|
<p class="exemple"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Choisissez un motif de sortie</h3>
|
<fieldset>
|
||||||
|
<legend class="title-3">Choisissez le ou les motif(s) de sortie</legend>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-travail" value="travail">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-travail" value="travail">
|
||||||
<label class="form-check-label" for="checkbox-travail">Déplacements entre le domicile et le lieu d’exercice de l’activité professionnelle, lorsqu'ils sont indispensables à l'exercice d’activités ne pouvant être organisées sous forme de télétravail ou déplacements professionnels ne pouvant être différés.</label>
|
<label class="form-check-label" for="checkbox-travail">Déplacements entre le domicile et le lieu d’exercice de l’activité professionnelle, lorsqu'ils sont indispensables à l'exercice d’activités ne pouvant être organisées sous forme de télétravail ou déplacements professionnels ne pouvant être différés.</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-courses" value="courses">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-courses" value="courses">
|
||||||
<label class="form-check-label" for="checkbox-courses">Déplacements pour effectuer des achats de fournitures nécessaires à l’activité professionnelle et des achats de première nécessité dans des établissements dont les activités demeurent autorisées <a href="https://www.service-public.fr/particuliers/actualites/A13921" target="_blank">(liste sur gouvernement.fr)</a>.</label>
|
<label class="form-check-label" for="checkbox-courses">Déplacements pour effectuer des achats de fournitures nécessaires à l’activité professionnelle et des achats de première nécessité dans des établissements dont les activités demeurent autorisées <a href="https://www.service-public.fr/particuliers/actualites/A13921" target="_blank">(liste sur gouvernement.fr)</a>.</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-sante" value="sante">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-sante" value="sante">
|
||||||
<label class="form-check-label" for="checkbox-sante">Consultations et soins ne pouvant être assurés à distance et ne pouvant être différés ; consultations et soins des patients atteints d'une affection de longue durée.</label>
|
<label class="form-check-label" for="checkbox-sante">Consultations et soins ne pouvant être assurés à distance et ne pouvant être différés ; consultations et soins des patients atteints d'une affection de longue durée.</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-famille" value="famille">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-famille" value="famille">
|
||||||
<label class="form-check-label" for="checkbox-famille">Déplacements pour motif familial impérieux, pour l’assistance aux personnes vulnérables ou la garde d’enfants.</label>
|
<label class="form-check-label" for="checkbox-famille">Déplacements pour motif familial impérieux, pour l’assistance aux personnes vulnérables ou la garde d’enfants.</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-sport" value="sport">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-sport" value="sport">
|
||||||
<label class="form-check-label" for="checkbox-sport">Déplacements brefs, dans la limite d'une heure quotidienne et dans un rayon maximal d'un kilomètre autour du domicile, liés soit à l'activité physique individuelle des personnes, à l'exclusion de toute pratique sportive collective et de toute proximité avec d'autres personnes, soit à la promenade avec les seules personnes regroupées dans un même domicile, soit aux besoins des animaux de compagnie.</label>
|
<label class="form-check-label" for="checkbox-sport">Déplacements brefs, dans la limite d'une heure quotidienne et dans un rayon maximal d'un kilomètre autour du domicile, liés soit à l'activité physique individuelle des personnes, à l'exclusion de toute pratique sportive collective et de toute proximité avec d'autres personnes, soit à la promenade avec les seules personnes regroupées dans un même domicile, soit aux besoins des animaux de compagnie.</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-judiciaire" value="judiciaire">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-judiciaire" value="judiciaire">
|
||||||
<label class="form-check-label" for="checkbox-judiciaire">Convocation judiciaire ou administrative.</label>
|
<label class="form-check-label" for="checkbox-judiciaire">Convocation judiciaire ou administrative.</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-missions" value="missions">
|
<input class="form-check-input" type="checkbox" name="field-reason" id="checkbox-missions" value="missions">
|
||||||
<label class="form-check-label" for="checkbox-missions">Participation à des missions d’intérêt général sur demande de l’autorité administrative.</label>
|
<label class="form-check-label" for="checkbox-missions">Participation à des missions d’intérêt général sur demande de l’autorité administrative.</label>
|
||||||
</div>
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-datesortie">Date de sortie</label>
|
<label for="field-datesortie">Date de sortie</label>
|
||||||
<div class="input-group align-items-center">
|
<div class="input-group align-items-center">
|
||||||
<input type="date" class="form-control" id="field-datesortie" name="datesortie" placeholder="JJ/MM/YYYY" required>
|
<input type="date" class="form-control" id="field-datesortie" name="datesortie" placeholder="JJ/MM/YYYY" required>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-heure">Heure de sortie</label>
|
<label for="field-heuresortie">Heure de sortie</label>
|
||||||
<div class="input-group align-items-center">
|
<div class="input-group align-items-center">
|
||||||
<input type="time" class="form-control" id="field-heuresortie" name="heure" required>
|
<input type="time" class="form-control" id="field-heuresortie" name="heure" required>
|
||||||
<span class="validity"></span>
|
<span class="validity" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<p class="text-center mt-5">
|
<p class="text-center mt-5">
|
||||||
<button type="submit" class="btn btn-primary btn-attestation"> <span class="btn-text">Générer mon attestation</span></button>
|
<button type="button" id="generate-btn" class="btn btn-primary btn-attestation"><span ><i class="fa fa-file-pdf inline-block mr-1"></i> Générer mon attestation</span></button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="bg-primary d-none" id="snackbar">
|
<div class="bg-primary d-none" id="snackbar">
|
||||||
L'attestation est téléchargée sur votre appareil.
|
L'attestation est téléchargée sur votre appareil.
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
|
<p class="github">
|
||||||
|
Le code source de ce service est consultable sur <a href="https://github.com/LAB-MI/deplacement-covid-19" class="github-link">Github</a>.
|
||||||
|
</p>
|
||||||
<p class="label-mi">
|
<p class="label-mi">
|
||||||
Ministère de l'Intérieur - DNUM - SDIT
|
Ministère de l'Intérieur - DNUM - SDIT
|
||||||
</p>
|
</p>
|
||||||
|
@ -263,9 +267,11 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<div class="alert alert-danger d-none" role="alert" id="alert-facebook">
|
<div class="alert alert-info d-none" id="update-alert">
|
||||||
ATTENTION !! Vous utilisez actuellement le navigateur Facebook, ce générateur ne fonctionne pas correctement au
|
Une nouvelle version est disponible. Cliquer sur le bouton pour l'obtenir.
|
||||||
sein de ce navigateur ! Merci d'ouvrir Chrome sur Android ou bien Safari sur iOS.
|
<p class="text-right">
|
||||||
|
<button id="reload-btn" class="btn btn-info">Mettre à jour</button>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="./certificate.js"></script>
|
<script src="./certificate.js"></script>
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
@ -64,6 +64,10 @@ canvas {
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #000191;
|
||||||
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
@ -187,7 +191,7 @@ input:valid+span:after {
|
||||||
|
|
||||||
|
|
||||||
.btn-attestation {
|
.btn-attestation {
|
||||||
padding: 0.8em;
|
padding: 0.9em;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
@ -195,6 +199,10 @@ input:valid+span:after {
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-attestation:hover {
|
||||||
|
background-color: #3031C1;
|
||||||
|
}
|
||||||
|
|
||||||
.github {
|
.github {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -360,8 +368,23 @@ input:valid+span:after {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width:600px) {
|
||||||
|
.hide-on-desktop, * [aria-labelledby='hide-on-desktop'] {
|
||||||
|
display: none;
|
||||||
|
max-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#update-alert {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1em;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
Sitemap: https://media.interieur.gouv.fr/deplacement-covid-19/sitemap.xml
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset
|
||||||
|
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||||
|
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||||
|
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
|
||||||
|
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://media.interieur.gouv.fr/deplacement-covid-19/</loc>
|
||||||
|
<lastmod>2020-04-06T04:22:03+00:00</lastmod>
|
||||||
|
<priority>1.00</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://media.interieur.gouv.fr/deplacement-covid-19/confidentialite.html</loc>
|
||||||
|
<lastmod>2020-04-06T04:22:03+00:00</lastmod>
|
||||||
|
<priority>0.80</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://media.interieur.gouv.fr/deplacement-covid-19/index.html</loc>
|
||||||
|
<lastmod>2020-04-06T04:22:03+00:00</lastmod>
|
||||||
|
<priority>0.64</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
|
||||||
|
</urlset>
|