Première version

This commit is contained in:
Simon C 2023-06-15 12:17:18 +02:00
parent 5eaaf44dd7
commit 0c7ab742ea
53 changed files with 99532 additions and 1 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
node_modules

30
.eslintrc.json Normal file
View File

@ -0,0 +1,30 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"bootstrap": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"no-console": 0,
"quotes": ["error", "single"],
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore"
}
]
}
}

1
.gitignore vendored
View File

@ -2,5 +2,6 @@ hugo_stats.json
.hugo_build.lock
resources
public
assets/jsconfig.json
node_modules

1
.stylelintignore Normal file
View File

@ -0,0 +1 @@
node_modules

48
.stylelintrc.json Normal file
View File

@ -0,0 +1,48 @@
{
"extends": "stylelint-config-standard-scss",
"rules": {
"no-empty-source": null,
"scss/comment-no-empty": null,
"max-line-length": null,
"scss/at-extend-no-missing-placeholder": null,
"scss/dollar-variable-colon-space-after": null,
"scss/dollar-variable-empty-line-before": null,
"media-feature-range-notation": null,
"color-function-notation": null,
"alpha-value-notation": null,
"selector-id-pattern": null,
"selector-class-pattern": null,
"scss/no-global-function-names": null,
"number-max-precision": null,
"hue-degree-notation": null,
"value-no-vendor-prefix": null,
"property-no-vendor-prefix": null,
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"extend",
"at-root",
"debug",
"warn",
"error",
"if",
"else",
"for",
"each",
"while",
"mixin",
"include",
"content",
"return",
"function",
"tailwind",
"apply",
"responsive",
"variants",
"screen"
]
}
]
}
}

180
assets/scripts/annuaire.js Normal file
View File

@ -0,0 +1,180 @@
import { createOrUpdateMspInfo } from "./directus.js"
import { initMap, updateLayers, zoomIn, zoomOut } from "./leaflet.js"
const columns = {
finessET: 0,
name: 1,
name_long: 2,
dep: 3,
adresse: 4,
tel: 5,
categetab: 6,
siret: 7,
x: 8,
y: 9,
}
let dataCache;
async function getDataP4Pillon() {
if (dataCache) {
return dataCache
}
const data = await fetch('/data_p4pillon.json')
dataCache = data.json()
return dataCache
}
async function getData() {
const data = await fetch('/data.json')
return data.json()
}
function getName(msp, dataP4Pillon) {
return dataP4Pillon ? dataP4Pillon[0] : (msp[columns.name_long] ? msp[columns.name_long] : msp[columns.name])
}
function showInfo() {
const element = document.getElementById("info")
element.classList.remove("hidden")
}
function setTitle(title) {
const elements = document.getElementsByClassName("title")
for (const element of elements) {
element.innerHTML = title
}
}
function setContent(content) {
const element = document.getElementById("content")
element.innerHTML = content
}
function setPhone(phone) {
const element = document.getElementById("phone")
if (phone) {
element.href = "tel:" + phone
element.title = phone
element.classList.remove('hidden')
} else {
element.classList.add('hidden')
}
}
function setMail(mail) {
const element = document.getElementById("mail")
if (mail) {
element.href = "mailto:" + mail
element.title = mail
element.classList.remove('hidden')
} else {
element.classList.add('hidden')
}
}
function setWebsite(website) {
const element = document.getElementById("website")
if (website) {
element.href = website
element.title = website
element.classList.remove('hidden')
} else {
element.classList.add('hidden')
}
}
function getContent(msp, dataP4Pillon) {
return "Établissement FINESS N°" + msp[columns.finessET] +
(msp[columns.siret] != null ? "<br>SIREN : <a rel='noreferrer' target='_blank' href='https://data.inpi.fr/entreprises/" + msp[columns.siret].substring(0, 9) + "'>" + msp[columns.siret].substring(0, 9) + "</a>" : "") +
(dataP4Pillon ? "<br>" +
(dataP4Pillon[1] || dataP4Pillon[2] ? "<br>Leader : " + dataP4Pillon[1] + " " + dataP4Pillon[2] : "") +
(dataP4Pillon[3] ? "<br>Adhérent à l'association AVEC Santé : ✅" : "") +
(dataP4Pillon[4] ? "<br>Accord conventionnel interprofessionnel : ✅" : "")
: "")
}
const editLayoutElement = document.getElementById("editLayout")
function displayInfo(msp, dataP4Pillon) {
editLayoutElement.classList.add("hidden")
setTitle(getName(msp, dataP4Pillon))
setContent(getContent(msp, dataP4Pillon))
setPhone(msp[columns.tel])
setMail(msp[columns.mail])
setWebsite(msp[columns.web])
showInfo()
}
const layerMSPElement = document.getElementById("layerMSP")
const layerPharmacieElement = document.getElementById("layerPharmacie")
const mspData = {
nofinesset: document.getElementById("msp-nofinesset"),
nom: document.getElementById("msp-nom"),
prenom_leader: document.getElementById("msp-prenom_leader"),
nom_leader: document.getElementById("msp-nom_leader"),
avec_sante: document.getElementById("msp-avec_sante"),
accord_conventionnel_interprofessionnel: document.getElementById("msp-accord_conventionnel_interprofessionnel"),
}
window.displayLayout = async (id) => {
if (id == "editLayout") {
const dataP4Pillon = await getDataP4Pillon()
const msp = window.msp
const data = dataP4Pillon[msp[columns.finessET]]
console.log(dataP4Pillon)
console.log(msp)
console.log(data)
mspData.nofinesset.value = window.msp[columns.finessET]
mspData.nom.value = getName(msp, data)
mspData.prenom_leader.value = data ? data[1] : ""
mspData.nom_leader.value = data ? data[2] : ""
mspData.avec_sante.checked = data ? data[3] : false
mspData.accord_conventionnel_interprofessionnel.checked = data ? data[4] : false
}
document.getElementById(id).classList.remove('hidden')
}
function initZoomBtn() {
document.getElementById("btnMore").addEventListener('click', () => zoomIn())
document.getElementById("btnLess").addEventListener('click', () => zoomOut())
}
function initCloseLayoutBtn() {
[...document.getElementsByClassName("btnClose")].forEach(btnCloseElement => {
btnCloseElement.addEventListener('click', () => {
btnCloseElement.parentNode.parentNode.classList.add("hidden")
console.log(btnCloseElement.parentNode.parentNode.id)
if (btnCloseElement.parentNode.parentNode.id == "info") {
editLayoutElement.classList.add("hidden")
}
})
});
}
async function initForms() {
document.getElementById("formInfo").addEventListener('submit', async (event) => {
event.preventDefault();
try {
const formData = new FormData(event.target)
const response = await createOrUpdateMspInfo(formData);
console.log(response)
} catch (error) {
console.error(error);
}
})
}
async function launchAnnuaire() {
var data = await getData()
var dataP4Pillon = await getDataP4Pillon()
layerMSPElement.addEventListener('change', () => updateLayers(layerMSPElement.checked, layerPharmacieElement.checked));
layerPharmacieElement.addEventListener('change', () => updateLayers(layerMSPElement.checked, layerPharmacieElement.checked));
initMap(data, dataP4Pillon, columns, getName, displayInfo, layerMSPElement.checked, layerPharmacieElement.checked)
initZoomBtn()
initCloseLayoutBtn()
initForms()
}
launchAnnuaire()

View File

@ -0,0 +1,64 @@
import { Directus, EmptyParamError } from '@directus/sdk';
const directus = new Directus('https://formulaire.p4pillon.org');
const mspInfo = directus.items('MSP_INFO');
export async function login() {
// AUTHENTICATION
let authenticated = false;
// Try to authenticate with token if exists
await directus.auth
.refresh()
.then(() => {
authenticated = true;
})
.catch(() => {});
// Let's login in case we don't have token or it is invalid / expired
while (!authenticated) {
const email = window.prompt('Email:');
const password = window.prompt('Password:');
await directus.auth
.login({ email, password })
.then(() => {
authenticated = true;
})
.catch(() => {
window.alert('Invalid credentials');
});
}
}
export async function createOrUpdateMspInfo(formData) {
try {
return await mspInfo.createOne({
nofinesset: formData.get("nofinesset"),
nom: formData.get("nom"),
prenom_leader: formData.get("prenom_leader"),
nom_leader: formData.get("nom_leader"),
avec_sante: formData.get("avec_sante"),
accord_conventionnel_interprofessionnel: formData.get("accord_conventionnel_interprofessionnel")
})
} catch (error) {
console.log(error)
}
const nofinesset = formData.get("nofinesset")
console.log(nofinesset)
try {
const msp = await mspInfo.readOne(nofinesset)
return await mspInfo.updateOne(nofinesset, formData)
} catch (error) {
if (error instanceof EmptyParamError) {
console.error("Le nofinesset est obligatoire.")
throw error
}
if (error.message == "You don't have permission to access this.") {
console.log("createOne")
console.log(formData)
return await mspInfo.createOne(formData)
}
}
}

0
assets/scripts/finess.js Normal file
View File

133
assets/scripts/leaflet.js Normal file
View File

@ -0,0 +1,133 @@
//
// Map
//
var map = L.map('map', {
zoomControl: false,
attributionControl: false
})
//
// Icons
// doc : https://onestepcode.com/leaflet-markers-svg-icons/
//
const mspIcon = L.divIcon({
html: `
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.4453 6.16795C16.7812 5.94402 17.2188 5.94402 17.5547 6.16795L23.5547 10.1679C23.8329 10.3534 24 10.6656 24 11V19C24 19.5523 23.5523 20 23 20H11C10.4477 20 10 19.5523 10 19V11C10 10.6656 10.1671 10.3534 10.4453 10.1679L16.4453 6.16795ZM16 18H18V14H16V18ZM20 18V13C20 12.4477 19.5523 12 19 12H15C14.4477 12 14 12.4477 14 13V18H12V11.5352L17 8.20185L22 11.5352V18H20Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.4961 12.1318C34.1887 11.9561 33.8113 11.9561 33.5039 12.1318L26.5039 16.1318C26.1923 16.3098 26 16.6411 26 17V27C26 27.5523 26.4477 28 27 28H41C41.5523 28 42 27.5523 42 27V17C42 16.6411 41.8077 16.3098 41.4961 16.1318L34.4961 12.1318ZM37 26H40V17.5803L34 14.1518L28 17.5803V26H31V20C31 19.4477 31.4477 19 32 19H36C36.5523 19 37 19.4477 37 20V26ZM35 26V21H33V26H35Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.4472 28.1056L15.4472 24.1056C15.1657 23.9648 14.8343 23.9648 14.5528 24.1056L6.55279 28.1056C6.214 28.275 6 28.6212 6 29V41C6 41.5523 6.44772 42 7 42H23C23.5523 42 24 41.5523 24 41V29C24 28.6212 23.786 28.275 23.4472 28.1056ZM16 34V40H14V34H16ZM18 33V40H22V29.618L15 26.118L8 29.618V40H12V33C12 32.4477 12.4477 32 13 32H17C17.5523 32 18 32.4477 18 33Z" fill="currentColor"/>
</svg>
`,
className: "",
iconSize: [48, 48],
iconAnchor: [12, 40],
});
const pharmacyIcon = L.divIcon({
html: `
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.8708 16.5029L26.5001 16.5029C27.0523 16.5029 27.5001 16.0552 27.5001 15.5029C27.5001 14.9506 27.0523 14.5029 26.5001 14.5029L23.8708 14.5029C23.5214 14.503 23.1149 14.56 22.7209 14.7523C21.2959 15.4476 20.4893 16.6497 20.0467 17.8209C19.8971 18.2165 19.786 18.6158 19.7045 19.0029H21.7622C21.8068 18.8436 21.8583 18.6846 21.9175 18.528C22.2394 17.6764 22.7625 16.9573 23.5979 16.5497C23.6444 16.527 23.7301 16.5029 23.8708 16.5029ZM18.0001 20.0029C17.4478 20.0029 16.9874 20.4588 17.1366 20.9906C17.7143 23.05 20.0631 24.6522 23.0001 24.9523V26.5105C22.3051 26.5275 21.5829 26.5829 20.9705 26.7612C20.492 26.9005 19.9849 27.1393 19.5969 27.575C19.1907 28.0312 19 28.6074 19 29.25C19 29.8932 19.1902 30.47 19.5958 30.9272C19.9836 31.3641 20.4906 31.6038 20.9696 31.7437C21.2897 31.8372 21.6397 31.897 22 31.9353V29.9217C21.8289 29.8972 21.6722 29.8653 21.5305 29.8239C21.2595 29.7448 21.1415 29.6558 21.0918 29.5997C21.0599 29.5638 21 29.4833 21 29.25C21 29.0191 21.0594 28.9401 21.0907 28.905C21.1402 28.8493 21.2581 28.7605 21.5296 28.6814C21.9135 28.5697 22.4074 28.5277 23.0001 28.5121V29.9938L23 31.9954L23.0001 34.0029H20.0001V36.0029H28.0001V34.0029H25.0001V28.4661C26.1018 28.3797 26.9948 28.1376 27.6667 27.7046C28.6123 27.0953 29 26.1881 29 25.2252C29 24.7019 28.8853 24.199 28.6292 23.7536C29.754 23.0448 30.5574 22.0819 30.8635 20.9906C31.0127 20.4588 30.5523 20.0029 30.0001 20.0029H18.0001ZM26.5833 26.0235C26.3 26.2061 25.8089 26.3795 25.0001 26.4584V24.9523C25.6205 24.8889 26.2147 24.7674 26.7715 24.5957C26.9363 24.7528 27 24.9436 27 25.2252C27 25.5956 26.8878 25.8272 26.5833 26.0235Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32 32H42V16H32V6H16V16H6V32H16V42H32V32ZM30 40V30H40V18H30V8H18V18H8V30H18V40H30Z" fill="currentColor"/>
</svg>
`,
className: "",
iconSize: [48, 48],
iconAnchor: [12, 40],
});
//
// Markers
//
const markersMSP = new L.MarkerClusterGroup({ chunkedLoading: true });
const markersPharmacy = new L.MarkerClusterGroup({ chunkedLoading: true });
export function updateLayers(layerMSPChecked, layerPharmacieChecked) {
// MSP
if (layerMSPChecked && !map.hasLayer(markersMSP)) {
map.addLayer(markersMSP)
} else if (!layerMSPChecked && map.hasLayer(markersMSP)) {
map.removeLayer(markersMSP)
}
//Pharmacy
if (layerPharmacieChecked && !map.hasLayer(markersPharmacy)) {
map.addLayer(markersPharmacy)
} else if (!layerPharmacieChecked && map.hasLayer(markersPharmacy)) {
map.removeLayer(markersPharmacy)
}
}
export function initMap(data, dataP4Pillon, columns, getName, displayInfo, layerMSPChecked, layerPharmacieChecked) {
for (const msp of data) {
if (msp[columns.x] && msp[columns.y]) {
const isMSP = msp[columns.categetab] == "603"
const marker = L.marker([msp[columns.x], msp[columns.y]], {
title: getName(msp, dataP4Pillon[msp[columns.finessET]]),
icon: isMSP ? mspIcon : pharmacyIcon
})
.on("click", (e)=> {
window.msp = msp
displayInfo(msp, dataP4Pillon[msp[columns.finessET]])
});
isMSP ? markersMSP.addLayer(marker) : markersPharmacy.addLayer(marker)
}
}
if (layerMSPChecked) {
map.addLayer(markersMSP)
}
if (layerPharmacieChecked) {
map.addLayer(markersPharmacy)
}
}
// tileLayer
var tileLayer = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
maxZoom: 19,
subdomains: 'abcd',
attribution: ''
})
map.addLayer(tileLayer)
// Localisation
function getMapLocation() {
const mapLocation = L.Permalink.getMapLocation();
const mapLocationDefaultCenter = [52.26869,-113.81034]
const defaultCenter = [46.55886, 3.21924]
const defaultZoom = 6
function isDefaultCenter() {
return JSON.stringify(mapLocation.center) == JSON.stringify(defaultCenter)
}
return {
getCenter : () => {
return isDefaultCenter() ? defaultCenter : mapLocation.center
},
getZoom : () => {
return isDefaultCenter() ? defaultZoom : mapLocation.zoom
},
}
}
const mapLocation = getMapLocation();
map.setView(mapLocation.getCenter(), mapLocation.getZoom())
// Zoom
export function zoomIn() {
map.zoomIn()
}
export function zoomOut() {
map.zoomOut()
}
// Changement d'URL
L.Permalink.setup(map);

19
assets/scripts/main.js Normal file
View File

@ -0,0 +1,19 @@
function menu() {
const menuElement = document.getElementById("menu")
const menuOpenElement = document.getElementById("menuOpen")
const menuCloseElement = document.getElementById("menuClose")
menuOpenElement.addEventListener('click', function () {
console.log("open")
menuElement.classList.toggle('hidden')
})
menuCloseElement.addEventListener('click', function () {
console.log("close")
menuElement.classList.toggle('hidden')
})
}
function launch() {
menu()
}
launch()

View File

@ -0,0 +1 @@
@import "buttons.css";

View File

21
assets/styles/styles.css Normal file
View File

@ -0,0 +1,21 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "components/all.css";
html {
font-size: 14px;
}
@screen md {
html {
font-size: 16px;
}
}
@layer components {
.btn-primary {
@apply rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600;
}
}

View File

@ -0,0 +1,24 @@
baseURL: https://p4pillon.org
disableKinds:
- taxonomy
- term
module:
hugoVersion:
extended: false
min: 0.112.0
mounts:
- source: assets
target: assets
- source: hugo_stats.json
target: assets/watching/hugo_stats.json
build:
writeStats: true
cachebusters:
- source: assets/watching/hugo_stats\.json
target: styles\.css
- source: (postcss|tailwind)\.config\.js
target: css
- source: assets/.*\.(js|ts|jsx|tsx)
target: js
- source: assets/.*\.(.*)$
target: $1

View File

@ -0,0 +1,7 @@
baseURL: https://staging.p4pillon.org/
deployment:
targets:
- name: staging
URL: >-
s3://staging.p4pillon.org?endpoint=https://s3.garage.resilien.cloud&disableSSL=true&s3ForcePathStyle=true&region=garage

7
content/_index.md Normal file
View File

@ -0,0 +1,7 @@
---
title: Pour une santé en commun et des communs en santé
---
P4Pillon.org est une association loi 1901 qui préfigure d'une [société coopérative d'intérêt collectif](https://fr.wikipedia.org/wiki/Soci%C3%A9t%C3%A9_coop%C3%A9rative_d%27int%C3%A9r%C3%AAt_collectif) ayant pour objet la création et la mise à disposition de [communs informationnels](https://fr.wikipedia.org/wiki/Biens_communs_informationnels) aux citoyens, patients et professionnels qui œuvrent sur un même territoire de santé.
P4Pillon investigue 4 thématiques interdépendantes : les organisations humaines en santé, les technologies de l'information et de la communication, les pratiques professionnelles, et la santé communautaire et planétaire.

View File

@ -0,0 +1,6 @@
---
title: Annuaire
section: annuaire
---
test

12
content/footer.md Normal file
View File

@ -0,0 +1,12 @@
---
headless: true
---
## P4PILLON
P4Pillon est une initiative de recherche et développement en santé et en soins de premiers recours
- [Mentions légales](/mentions-legales/)
- [Politique de confidentialité](/politique-de-confidentialite/)
- Site éco-conçu 🪶 par [Weko](https://weko.io)
- Hébergé avec sobriété ⚡ par [RésiLien](https://resilien.fr)

35
content/notre-histoire.md Normal file
View File

@ -0,0 +1,35 @@
---
title: Notre histoire
draft: false
---
# Notre histoire
## L'origine
Dès 2009, les professionnels de santé installés sur la montagne limousine ont pris conscience des enjeux de soutenabilité et de résilience de l'offre de soins vis à vis d'une désertification médicale annoncée par les projections démographiques.
## La contrainte forge l'innovation
Ce territoire est marqué par des contraintes géographiques (zone de moyenne montagne et habitat dispersé), démographiques (population âgée et fragile) et épidémiologiques (forte prévalence des maladies chroniques et des besoins en prévention). Ainsi, il nous semblait être un terrain idéal pour expérimenter et identifier des leviers dadaptation du système de santé aux enjeux de notre société.
## Agir en communauté de pensée, penser en communauté d'action
En 2014, les professionnels se sont constitués en équipe coordonnée en santé dans la ligne politique portée par l'association AVEC Santé. Cette démarche correspond à la définition ou la création de différents communs :
- définition d'un périmètre d'action commun : cette étape permet d'analyser les caractéristiques du territoire en terme de besoins afin d'y adapter une offre de soins. Dans notre cas, c'est l'exercice dit "multi-sites" ou décentralisé qui a été choisi pour des questions de contraintes géographiques.
- adoption d'un projet de santé commun à l'équipe : suite au diagnostic territorial, un projet de santé prenant en compte les données de santé publique est rédigé puis signé par les différents professionnels de santé ou intervenants. Dans notre cas, l'accent est mis sur la prise en charge des pathologies chroniques, la prévention et l'organisation des soins non programmés (urgences)
- partage de lieux d'exercice communs : plusieurs cabinets médicaux sont mis à disposition et partagés entre professionnels de santé afin qu'il puissent répartir leur offre de soins sur tout le territoire.
- création d'un commun juridique : la constitution en Société Interprofessionnelle de Soins Ambulatoires (SISA) créé une personne morale porteuse du projet de santé ce qui facilite les règles d'accès aux dossiers médicaux et la mise en place d'une fonction de coordination de l'équipe.
- attribution de financement communs : suite à l'acceptation du projet de santé par l'agence régionale de santé, la SISA peut bénéficier de financements commun via la signature d'une convention avec l'assurance maladie. Ces financements viennent rompre avec la logique historique du financement à l'activité des professionnel de santé, ils sont attribués à une équipe pluriprofessionnelle en fonction de la taille de sa patientèle (financement par capitation).
- acquisition d'un système d'information partagé permettant la création d'un commun informationnel : ces logiciels hébergent les dossiers médicaux et permettent une coordination des différents professionnels autour du patient. L'accès à une information partagé implique une production participative de l'information et donc la création d'un commun informationnel reflétant l'état de santé du territoire d'action de l'équipe.
## Particularité pharmaceutique du projet
En 2016, la pharmacie de Bugeat est reprise par Antoine Prioux, actuellement président de l'association P4Pillon. Dans son travail de thèse soutenu en 2013, il jetait les base d'une intégration des pharmaciens d'officine au sein de l'équipe coordonnée afin d'améliorer la prise en charge pharmaco-thérapeutique des patients.
Quelques mois plus tard il est rejoint par Eliza Castagné, pharmacienne clinicienne ayant travaillé sur la iatrogénie médicamenteuse et Julien Misiak, ingénieur en informatique et créateur d'un logiciel de gestion d'officine. Cette étape marque le point de départ de l'expérimentation en vie réelle qui aboutira après quelques années à plusieurs preuves de concept autour du design des systèmes d'information et du traitement de données de santé à des fins de maintien en bonne santé de la population.
## Objectif : h4cker le système
P4Pillon collabore et interagit actuellement avec de nombreuses personnes et associations militantes afin de construire et éprouver un récit de transition où la santé au sens large (planétaire) serait le principal argument pour composer une société soutenable et résiliente basée sur les communs et la justice sociale.

View File

@ -0,0 +1,13 @@
---
title: Qui sommes nous ?
---
# Qui sommes nous ?
La volonté de transformation du système de santé portée par P4Pillon émane de la détermination d'une équipe coordonnée en santé : le pôle Millesoins.
Juridiquement constituée en Société Interprofessionnelle de Soins Ambulatoires (SISA), cette structure adhère au mouvement AVEC Santé qui plaide pour une refondation des soins de premier recours par un exercice pluriprofessionnel coordonné et un partenariat fort avec la population du territoire (santé communautaire).
Cette équipe est composée de médecins généralistes, de pharmacien.ne.s, et d'infirmier.e.s qui collaborent avec des chercheur.se.s pluridisciplinaires, des ingénieur.e.s et diverses associations militantes dans les champs du logiciel libre, de la médecine sociale et de la santé planétaire.
P4Pillon est une association à but non lucratif qui préfigure d'une Société Coopérative d'Intérêt Collectif (SCIC) dont la principale mission est de promouvoir et créer des communs numériques en santé (logiciels libres et bases de données autogérées).

View File

@ -0,0 +1,4 @@
---
---
En cours de développement

27
layouts/404.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en" class="h-full">
{{ partial "head.html" . }}
<body class="h-full">
<main class="grid min-h-full place-items-center bg-white px-6 py-24 sm:py-32 lg:px-8">
<div class="text-center">
<p class="text-base font-semibold text-indigo-600">
404
</p>
<h1 class="mt-4 text-3xl font-bold tracking-tight text-gray-900 sm:text-5xl">
Page non trouvée
</h1>
<p class="mt-6 text-base leading-7 text-gray-600">
Désolé la page que vous cherchez n'existe pas ou a changé de place.
</p>
<div class="mt-10 flex items-center justify-center gap-x-6">
<a href="/" class="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
Revenir à la page d'accueil
</a>
<a href="mailto:support@p4pillon.org" class="text-sm font-semibold text-gray-900">
Contacter le support <span aria-hidden="true">&rarr;</span>
</a>
</div>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="fr" class="h-full">
<head>
{{ partial "head.html" . }}
</head>
<body class="h-full">
<div class="container mx-auto">
<div class="bg-white">
{{ partial "header.html" . }}
</div>
{{ block "main" . }}{{ end }}
</div>
{{ partial "footer.html" . }}
{{ partial "scripts.html" . }}
</body>
</html>

View File

@ -0,0 +1,8 @@
{{ define "main" }}
{{ .Content }}
<ul>
{{ range .Pages }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
{{ end }}
</ul>
{{ end }}

View File

@ -0,0 +1,9 @@
{{ define "main" }}
<div class="relative w-full bg-white my-20 px-6 py-12 shadow-xl shadow-slate-700/10 ring-1 ring-gray-900/5 md:mx-auto md:max-w-3xl lg:max-w-4xl lg:py-16">
<div class="mx-auto max-w-prose lg:text-lg">
<article class="prose prose-slate mx-auto lg:prose-xl">
{{ .Content }}
</article>
</div>
</div>
{{ end }}

View File

@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="fr" class="h-full">
<head>
{{ partial "head.html" . }}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.1/dist/leaflet.css" integrity="sha256-sA+zWATbFveLLNqWO2gtiw3HL/lh1giY/Inf1BJ0z14=" crossorigin=""/>
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" crossorigin=""/>
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" crossorigin=""/>
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" />
<script src="https://unpkg.com/leaflet@1.9.1/dist/leaflet.js" integrity="sha256-NDI0K41gVbWqfkkaHj15IzU7PtMoelkzyKp8TOaFQ3s=" crossorigin=""></script>
<script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js" crossorigin=""></script>
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
<script src="/leaflet.permalink.js"></script>
</head>
<body class="h-full relative">
<div class="bg-white">
{{ partial "header.html" . }}
</div>
<div class="absolute sm:bg-opacity-80 left-0 bottom-0 right-0 h-14 w-full max-w-none sm:w-80 sm:right-auto sm:left-4 sm:bottom-4 z-20 border-t sm:border border-green-700 bg-white sm:rounded-lg shadow-2xl p-4 text-center">
<label class="inline-flex items-center mr-4">
<input class="text-green-700" id="layerMSP" type="checkbox" checked="">
<span class="ml-2">Maison de santé</span>
</label>
<label class="inline-flex items-center">
<input class="text-green-700" id="layerPharmacie" type="checkbox">
<span class="ml-2">Officine</span>
</label>
</div>
<div id="info" class="hidden sm:bg-opacity-80 absolute left-0 bottom-14 sm:bottom-24 right-0 sm:right-auto sm:left-4 w-full max-w-none sm:w-80 z-20 border-t sm:border border-green-700 bg-white sm:rounded-lg sm:shadow-2xl prose">
<!-- Modal content -->
<!-- Modal header -->
<div class="flex items-center justify-between p-4 border-b rounded-t-lg">
<h4 class="title text-xl font-semibold text-gray-900 my-0">
MAISON DE SANTE (MSP) DE SAINT CHELY D'APCHER (48)
</h4>
<button type="button" class="btnClose bg-transparent border border-white hover:border-green-700 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex self-start" data-modal-hide="staticModal">
<svg class="w-5 h-5 stroke-green-700" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
</div>
<!-- Modal body -->
<div class="p-4 space-y-6">
<p id="content" class="text-base leading-relaxed text-gray-500 my-0">
Établissement FINESS N°480002732<br>
SIREN : 837840933
</p>
</div>
<!-- Modal footer -->
<div id="contact" class="flex justify-center items-center p-4 space-x-4 border-t border-gray-200 rounded-b-lg">
<a id="phone" href="tel:0448250145" title="04 48 25 01 45" data-modal-hide="staticModal" type="button" class="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-2 py-2 text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 sm:w-5 sm:h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 002.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 01-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 00-1.091-.852H4.5A2.25 2.25 0 002.25 4.5v2.25z" />
</svg>
</a>
<a id="mail" href="tel:0448250145" title="04 48 25 01 45" data-modal-hide="staticModal" type="button" class="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-2 py-2 text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 sm:w-5 sm:h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
</svg>
</a>
<a id="website" href="tel:0448250145" title="04 48 25 01 45" data-modal-hide="staticModal" type="button" class="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-2 py-2 text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 sm:w-5 sm:h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25" />
</svg>
</a>
<button id="edit" onclick="displayLayout('editLayout')" title="Éditer" data-modal-hide="staticModal" type="button" class="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-2 py-2 text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 sm:w-5 sm:h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
</svg>
</button>
</div>
</div>
<div id="editLayout" class="hidden overflow-auto layout absolute sm:bg-opacity-90 left-0 sm:left-80 lg:left-auto sm:ml-8 top-20 bottom-14 sm:bottom-4 right-0 sm:right-4 lg:right-16 w-full sm:w-auto max-w-none lg:max-w-md z-30 border-t sm:border border-green-700 bg-white sm:rounded-lg sm:shadow-2xl prose">
<div class="flex items-center justify-between p-4 border-b rounded-t-lg">
<h4 class="title text-xl font-semibold text-gray-900 my-0">
MAISON DE SANTE (MSP) DE SAINT CHELY D'APCHER (48)
</h4>
<button type="button" class="btnClose bg-transparent border border-white hover:border-green-700 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex self-start" data-modal-hide="staticModal">
<svg class="w-5 h-5 stroke-green-700" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
</div>
<!-- Modal body -->
<div class="p-4 space-y-6">
<form id="formInfo" method="POST" action="https://formulaire.p4pillon.org/items/MSP_INFO">
<div class="grid grid-cols-1 gap-6">
<label class="block">
<span class="text-gray-700">Nofinesset</span>
<input id="msp-nofinesset" type="text" name="nofinesset" class="mt-1 block w-full" placeholder="">
</label>
<label class="block">
<span class="text-gray-700">Nom</span>
<input id="msp-nom" type="text" name="nom" class="mt-1 block w-full" placeholder="">
</label>
<label class="block">
<span class="text-gray-700">Prénom Leader</span>
<input id="msp-prenom_leader" type="text" name="prenom_leader" class="mt-1 block w-full" placeholder="">
</label>
<label class="block">
<span class="text-gray-700">Nom Leader</span>
<input id="msp-nom_leader" type="text" name="nom_leader" class="mt-1 block w-full" placeholder="">
</label>
<div class="block">
<label class="inline-flex items-center">
<input id="msp-avec_sante" type="checkbox" checked="" name="avec_sante">
<span class="ml-2">Avec santé</span>
</label>
</div>
<div class="block">
<label class="inline-flex items-center">
<input id="msp-accord_conventionnel_interprofessionnel" type="checkbox" checked="" name="accord_conventionnel_interprofessionnel">
<span class="ml-2">Accord Conventionnel Interprofessionnel</span>
</label>
</div>
</div>
<div class="block">
<button type="submit" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Envoyer</button>
</div>
</form>
<fieldset class="hidden">
<legend>informations générales</legend>
<label for="noms">Nom de la structure :</label>
<input type="text" name="structure" placeholder="nom de la SISA" required="required">
<label for="ville">Ville :</label>
<input type="text" name="structure" placeholder="ville" required="required">
<label for="code">Code postal :</label>
<input type="text" name="structure" placeholder="Ex: 87000" required="required">
<label for="rue"> Rue :</label>
<input type="text" name="structure" placeholder="Ex: " required="required">
<!-- A mettre : dans un premier temps pouvoir mettre un chiffre puis dans un second temps le ventiullé sur le type de praticien -->
<label for="npro">Nombre professionnels</label>
<select>
<option selected>Choisissez</option>
<option>moins de 16 professionnels</option>
<option>plus de 16 professionnels</option>
</select>
<div class="open">
<!-- A mettre -->
<label for="ipa">Présence d'un IPA dans l'équipe</label>
<label for="yes">Oui</label><input type="radio" name="yes" id="yes" /><label for="no">Non</label><input
type="radio" name="no" id="no" />
</div>
<div class="open">
<!-- A mettre -->
<label for="ipam">Formation des jeunes professionnels de santé</label>
<label for="prof_sant_yes">Oui</label><input type="radio" name="prof_sant" value="true"
id="prof_sant_yes" /><label for="no">Non</label><input type="radio" name="no" id="no" />
</div>
<div class="open">
<!-- A mettre + champ pour citer le logiciel utilisé (il faut la liste) -->
<!-- Système d'information labellisé : -->
<!-- https://esante.gouv.fr/offres-services/label-esante/solutions-labellisees -->
<label for="sina">Système d'information labellisé niveau avancé (ASIP Santé)</label>
<label for="yes">Oui</label><input type="radio" name="yes" id="yes" /><label for="no">Non</label><input
type="radio" name="no" id="no" />
</div>
<input type="submit" name="submit" value="ENVOYER">
</fieldset>
</div>
</div>
<div id="zoom" class="hidden sm:flex flex-col-reverse items-center justify-between absolute bottom-4 right-4 w-8 h-16 z-20 sm:shadow-2xl">
<button id="btnLess" type="button" class="p-1.5 bg-white border rounded-b-lg border-green-700 hover:bg-green-700 stroke-green-700 stroke-2 hover:stroke-white" data-modal-hide="staticModal">
<svg class="w-full h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
</svg>
</button>
<button id="btnMore" type="button" class="p-1.5 bg-white border-t border-x rounded-t-lg border-green-700 hover:bg-green-700 stroke-green-700 stroke-2 hover:stroke-white" data-modal-hide="staticModal">
<svg class="w-full h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
</button>
</div>
<div class="absolute w-screen h-screen bottom-0 left-0 top-0 right-0 z-10">
<div id="map" style="width: 100%; height: 100%;" class=""></div>
</div>
{{ $js := resources.Get "scripts/annuaire.js" }}
{{ with $js }}
{{ $secureJS := . | js.Build }}
{{ if not $.Site.Params.debug }}
{{ $secureJS = $secureJS | minify }}
{{ end }}
{{ $secureJS = $secureJS | fingerprint }}
<script type="module" src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>
{{ end }}
{{ partial "scripts.html" . }}
</body>
</html>

11
layouts/index.html Normal file
View File

@ -0,0 +1,11 @@
{{ define "main" }}
{{ partial "heroe" . }}
<div class="relative w-full bg-white mb-32 px-6 py-12 shadow-xl shadow-slate-700/10 ring-1 ring-gray-900/5 md:mx-auto md:max-w-3xl lg:max-w-4xl lg:py-16">
<div class="mx-auto max-w-prose lg:text-lg">
<article class="prose prose-slate mx-auto lg:prose-xl">
{{ .Content }}
</article>
</div>
</div>
{{ partial "newsletter.html" . }}
{{ end }}

View File

@ -0,0 +1,36 @@
<!--
Heads up! 👋
This component comes with some `rtl` classes. Please remove them if they are not needed in your project.
-->
<footer class="bg-white">
<div class="mx-auto max-w-screen-xl px-4 pb-6 pt-6 sm:px-6 lg:px-8">
<div class="border-gray-100">
<div class="text-center sm:flex sm:justify-between sm:text-left">
<p class="text-sm text-gray-500">
<a
class="inline-block text-green-700 underline transition hover:text-teal-600/75"
href="/"
>
Politique de confidentialité
</a>
<span>&middot;</span>
<a
class="inline-block text-green-700 underline transition hover:text-teal-600/75"
href="/"
>
Mentions légales
</a>
</p>
<p class="mt-4 text-sm text-gray-500 sm:order-first sm:mt-0">
&copy; 2023 P4Pillon
</p>
</div>
</div>
</div>
</footer>

View File

@ -0,0 +1,16 @@
<meta charset="utf-8" />
<title>
{{ .Title }}
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{{ .Description }}" />
{{/* styles */}}
{{ $options := dict "inlineImports" true }}
{{ $styles := resources.Get "styles/styles.css" }}
{{ $styles = $styles | resources.PostCSS $options }}
{{ if hugo.IsProduction }}
{{ $styles = $styles | minify | fingerprint | resources.PostProcess }}
{{/* {{ else }}
<link href="/tailwindcss.css" rel="stylesheet" /> */}}
{{ end }}
<link href="{{ $styles.RelPermalink }}" rel="stylesheet" />

View File

@ -0,0 +1,57 @@
<header class="absolute inset-x-0 top-0 z-50">
<nav class="flex items-center justify-between p-6 lg:px-8" aria-label="Global">
<div class="flex lg:flex-1">
<a href="/" class="-m-1.5 p-1.5 flex items-center justify-center">
<img class="h-8 w-auto" src="/p4pillon-cyan-400.png" alt="">
<span class="pl-4 text-2xl font-black text-green-700">P4Pillon</span>
</a>
</div>
<div class="flex lg:hidden">
<button id="menuOpen" type="button" class="-m-2.5 border border-emerald-700 bg-white shadow-2xl inline-flex items-center justify-center rounded-md p-2.5 text-gray-700">
<span class="sr-only">Open main menu</span>
<svg class="h-6 w-6 stroke-emerald-700" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
</div>
<div class="hidden lg:flex lg:gap-x-12">
<a href="/notre-histoire/" class="text-sm font-semibold leading-6 text-green-700">Histoire</a>
<a href="/qui-sommes-nous/" class="text-sm font-semibold leading-6 text-green-700">We 4re</a>
<a href="/annuaire/" class="text-sm font-semibold leading-6 text-green-700">Annuaire</a>
</div>
<div class="hidden lg:flex lg:flex-1 lg:justify-end">
<a href="/se-connecter/" class="text-sm font-semibold leading-6 text-green-700">Se connecter <span aria-hidden="true">&rarr;</span></a>
</div>
</nav>
<!-- Mobile menu, show/hide based on menu open state. -->
<div id="menu" class="hidden" role="dialog" aria-modal="true">
<!-- Background backdrop, show/hide based on slide-over state. -->
<div class="fixed inset-0 z-50"></div>
<div class="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div class="flex items-center justify-between">
<a href="/" class="-m-1.5 p-1.5 flex items-center justify-center">
<img class="h-8 w-auto" src="/p4pillon-cyan-400.png" alt="">
<span class="pl-4 text-2xl font-black text-green-700">P4Pillon</span>
</a>
<button id="menuClose" type="button" class="-m-2.5 rounded-md p-2.5 text-gray-700 border border-white hover:border-green-700">
<span class="sr-only">Close menu</span>
<svg class="h-6 w-6 stroke-green-700" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="mt-6 flow-root">
<div class="-my-6 divide-y divide-gray-500/10">
<div class="space-y-2 py-6">
<a href="/notre-histoire/" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-green-700 hover:bg-gray-50">Histoire</a>
<a href="/qui-sommes-nous/" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-green-700 hover:bg-gray-50">We 4re</a>
<a href="/annuaire/" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-green-700 hover:bg-gray-50">Annuaire</a>
</div>
<div class="py-6">
<a href="/se-connecter/" class="-mx-3 block rounded-lg px-3 py-2.5 text-base font-semibold leading-7 text-green-700 hover:bg-gray-50">Se connecter</a>
</div>
</div>
</div>
</div>
</div>
</header>

View File

@ -0,0 +1,28 @@
<div class="bg-white">
<div class="relative isolate px-6 pt-14 lg:px-8">
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true">
<div class="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]" style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"></div>
</div>
<div class="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
<div class="hidden sm:mb-8 sm:flex sm:justify-center">
<div class="relative rounded-full px-3 py-1 text-sm leading-6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
Prenez connaissance de l'historique du projet. <a href="/notre-histoire/" class="font-semibold text-indigo-600"><span class="absolute inset-0" aria-hidden="true"></span> <span aria-hidden="true">&rarr;</span></a>
</div>
</div>
<div class="text-center">
<h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">{{ .Title }}</h1>
<p class="mt-6 text-lg leading-8 text-gray-600">
P4Pillon est une initiative de recherche et développement en santé et en soins de premiers recours située sur la Montagne Limousine, au cœur du Parc Naturel Régional du Plateau de Millevaches.
</p>
<div class="mt-10 flex items-center justify-center gap-x-6">
<a href="/annuaire/" class="btn-primary">Voir l'annuaire</a>
<a href="/qui-sommes-nous/" class="text-sm font-semibold leading-6 text-gray-900">Qui somme-nous <span aria-hidden="true">?</span></a>
</div>
</div>
</div>
<div class="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]" aria-hidden="true">
<div class="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]" style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"></div>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
</div>
<div class="relative isolate overflow-hidden bg-gray-900 py-16 sm:py-24 lg:py-32">
<div class="mx-auto max-w-7xl px-6 lg:px-8">
<div class="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-2">
<div class="max-w-xl lg:max-w-lg">
<h2 class="text-3xl font-bold tracking-tight text-white sm:text-4xl">Lettre d'information</h2>
<p class="mt-4 text-lg leading-8 text-gray-300">Pour rester informer de notre évolution, nos différents avancées n'hésitez pas à vous inscrire.</p>
<div class="mt-6 flex max-w-md gap-x-4">
<label for="email-address" class="sr-only">Email address</label>
<input id="email-address" name="email" type="email" autocomplete="email" required class="min-w-0 flex-auto rounded-md border-0 bg-white/5 px-3.5 py-2 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-indigo-500 sm:text-sm sm:leading-6" placeholder="Entrer votre mail">
<button type="submit" class="flex-none rounded-md bg-indigo-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500">S'inscrire</button>
</div>
</div>
<dl class="grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2 lg:pt-2">
<div class="flex flex-col items-start">
<div class="rounded-md bg-white/5 p-2 ring-1 ring-white/10">
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5m-9-6h.008v.008H12v-.008zM12 15h.008v.008H12V15zm0 2.25h.008v.008H12v-.008zM9.75 15h.008v.008H9.75V15zm0 2.25h.008v.008H9.75v-.008zM7.5 15h.008v.008H7.5V15zm0 2.25h.008v.008H7.5v-.008zm6.75-4.5h.008v.008h-.008v-.008zm0 2.25h.008v.008h-.008V15zm0 2.25h.008v.008h-.008v-.008zm2.25-4.5h.008v.008H16.5v-.008zm0 2.25h.008v.008H16.5V15z" />
</svg>
</div>
<dt class="mt-4 font-semibold text-white">Un mail tous les semestres</dt>
<dd class="mt-2 leading-7 text-gray-400">Vous recevrez une lettre d'information tous les semestres</dd>
</div>
<div class="flex flex-col items-start">
<div class="rounded-md bg-white/5 p-2 ring-1 ring-white/10">
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.05 4.575a1.575 1.575 0 10-3.15 0v3m3.15-3v-1.5a1.575 1.575 0 013.15 0v1.5m-3.15 0l.075 5.925m3.075.75V4.575m0 0a1.575 1.575 0 013.15 0V15M6.9 7.575a1.575 1.575 0 10-3.15 0v8.175a6.75 6.75 0 006.75 6.75h2.018a5.25 5.25 0 003.712-1.538l1.732-1.732a5.25 5.25 0 001.538-3.712l.003-2.024a.668.668 0 01.198-.471 1.575 1.575 0 10-2.228-2.228 3.818 3.818 0 00-1.12 2.687M6.9 7.575V12m6.27 4.318A4.49 4.49 0 0116.35 15m.002 0h-.002" />
</svg>
</div>
<dt class="mt-4 font-semibold text-white">Pas de spam</dt>
<dd class="mt-2 leading-7 text-gray-400">Nous ne communiquons les mails à aucun partenaire, et vous pouvez vous désinscrire à chaque mail</dd>
</div>
</dl>
</div>
</div>
<div class="absolute left-1/2 top-0 -z-10 -translate-x-1/2 blur-3xl xl:-top-6" aria-hidden="true">
<div class="aspect-[1155/678] w-[72.1875rem] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30" style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"></div>
</div>

View File

@ -0,0 +1,9 @@
{{ $js := resources.Get "scripts/main.js" }}
{{ with $js }}
{{ $secureJS := . | js.Build }}
{{ if not $.Site.Params.debug }}
{{ $secureJS = $secureJS | minify }}
{{ end }}
{{ $secureJS = $secureJS | fingerprint }}
<script type="module" src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>
{{ end }}

View File

@ -0,0 +1,39 @@
{{ define "main" }}
<div class="absolu top-0 left-0 right-0 bottom-0 flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Connectez vous à votre compte</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" action="#" method="POST">
<div>
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Adresse mail</label>
<div class="mt-2">
<input id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Mot de passe</label>
<div class="text-sm">
<a href="#" class="font-semibold text-indigo-600 hover:text-indigo-500">Mot de passe oublié ?</a>
</div>
</div>
<div class="mt-2">
<input id="password" name="password" type="password" autocomplete="current-password" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Se connecter</button>
</div>
</form>
<p class="mt-10 text-center text-sm text-gray-500">
Not a member?
<a href="#" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Start a 14 day free trial</a>
</p>
</div>
</div>
{{ end }}

1697
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "p4pillon.org",
"version": "1.0.0",
"description": "Vous trouverez ici les sources du site WEB de P4Pillon",
"main": "index.js",
"scripts": {
"lint": "npm run -s lint:styles",
"lint:scripts": "eslint assets/scripts",
"lint:styles": "stylelint \"assets/styles/**/*.{css,sass,scss,sss,less}\"",
"test": "npm run -s lint"
},
"author": "",
"license": "AGPL-3.0",
"devDependencies": {
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.24",
"postcss-cli": "^10.1.0",
"tailwindcss": "^3.3.2"
},
"dependencies": {
"@directus/sdk": "^10.3.3"
}
}

11
postcss.config.js Normal file
View File

@ -0,0 +1,11 @@
let tailwindConfig = process.env.HUGO_FILE_TAILWIND_CONFIG_JS || './tailwind.config.js';
const tailwind = require('tailwindcss')(tailwindConfig);
const autoprefixer = require('autoprefixer');
module.exports = {
// eslint-disable-next-line no-process-env
plugins: [
tailwind,
...(process.env.HUGO_ENVIRONMENT === 'production' ? [autoprefixer] : []),
],
};

96069
scripts/finess-clean.csv Normal file

File diff suppressed because it is too large Load Diff

162
scripts/finess-clean.py Normal file
View File

@ -0,0 +1,162 @@
# -*- coding: utf-8 -*-
# ---
# jupyter:
# jupytext:
# formats: ipynb,py:hydrogen
# text_representation:
# extension: .py
# format_name: hydrogen
# format_version: '1.3'
# jupytext_version: 1.14.1
# kernelspec:
# display_name: Python 3 (ipykernel)
# language: python
# name: python3
# ---
# %% [markdown]
# # Production d'un csv utilisable de la base FINESS
#
# En l'état, l'export CSV de la [base FINESS][finess] n'est pas vraiment satisfaisant et utilisable.
#
# - Le fichier n'est pas réellement un CSV.
# - Il est bizarrement découpé en deux sections qui correspondent au XML.
# - Les colonnes n'ont pas de nom.
# - Le fichier est encodé au format windows.
#
# [finess]: https://www.data.gouv.fr/en/datasets/finess-extraction-du-fichier-des-etablissements/
# %% gradient={"editing": false, "id": "4facc182", "kernelId": ""}
import pandas as pd
import numpy as np
import requests
# %% gradient={"editing": false, "id": "3f7b5d32", "kernelId": ""}
dataset_api = "https://www.data.gouv.fr/api/1/datasets/finess-extraction-du-fichier-des-etablissements/"
# %% gradient={"editing": false, "id": "58d641d4", "kernelId": ""}
resources = (requests
.get(dataset_api)
.json()
['resources']
)
resource_geoloc = [ r for r in resources if r['type'] == 'main' and 'géolocalisés' in r['title']][0]
# %% gradient={"editing": false, "id": "13dd939b", "kernelId": ""}
headers = [
'section',
'nofinesset',
'nofinessej',
'rs',
'rslongue',
'complrs',
'compldistrib',
'numvoie',
'typvoie',
'voie',
'compvoie',
'lieuditbp',
'commune',
'departement',
'libdepartement',
'ligneacheminement',
'telephone',
'telecopie',
'categetab',
'libcategetab',
'categagretab',
'libcategagretab',
'siret',
'codeape',
'codemft',
'libmft',
'codesph',
'libsph',
'dateouv',
'dateautor',
'maj',
'numuai'
]
# %% gradient={"editing": false, "id": "b68dac89", "kernelId": ""}
geoloc_names = [
'nofinesset',
'coordxet',
'coordyet',
'sourcecoordet',
'datemaj'
]
# %% gradient={"editing": false, "id": "4492d3dd", "kernelId": ""}
raw_df = (pd
.read_csv(resource_geoloc['url'],
sep=";", encoding="utf-8", header=None, skiprows=1,
dtype='str',
names=headers)
.drop(columns=['section'])
)
raw_df
# %% gradient={"editing": false, "id": "2efc14bc", "kernelId": ""}
structures = (raw_df
.iloc[:int(raw_df.index.size/2)]
)
structures
# %% gradient={"editing": false, "id": "283be3bb", "kernelId": ""}
geolocalisations = (raw_df
.iloc[int(raw_df.index.size/2):]
.drop(columns=raw_df.columns[5:])
.rename(columns=lambda x: geoloc_names[list(raw_df.columns).index(x)])
)
geolocalisations
# %% gradient={"editing": false, "id": "b54e527e", "kernelId": ""}
clean_df = (structures
.merge(geolocalisations, on="nofinesset", how="left")
)
clean_df
# %%
clean_df.sample().T
# %%
clean_df["siret"]
# %% [markdown] gradient={"editing": false, "id": "82306369-229c-418f-9138-d753e1b71ce4", "kernelId": ""}
# ## Vérification de la qualité des données
# %% gradient={"editing": false, "id": "64975e82-5f97-4bb4-b1d3-8aed85fa37cd", "kernelId": "", "source_hidden": false} jupyter={"outputs_hidden": false}
intersection = pd.Series(np.intersect1d(structures.nofinesset.values, geolocalisations.nofinesset.values))
intersection.shape
# %% gradient={"editing": false, "id": "07e3c1cb-7032-4d83-833c-0979d2592f3c", "kernelId": "", "source_hidden": false} jupyter={"outputs_hidden": false}
only_structures = (structures
[ ~structures.nofinesset.isin(intersection) ]
)
only_structures
# %% gradient={"editing": false, "id": "cfb13e95-b622-4d89-be56-61397dc4370e", "kernelId": "", "source_hidden": false} jupyter={"outputs_hidden": false}
only_geolocalisations = (geolocalisations
[ ~geolocalisations.nofinesset.isin(intersection) ]
)
only_geolocalisations
# %% gradient={"editing": false, "id": "92cd9e34-74c8-454c-96d8-3c628e7b94bd", "kernelId": "", "source_hidden": false} jupyter={"outputs_hidden": false}
geolocalisations_missing = []
# %% [markdown] gradient={"editing": false, "id": "ff24d2da-6b7e-49ca-8ac9-cc1e90d32235", "kernelId": ""}
# ## Export final
# %% gradient={"editing": false, "id": "8f6f3c73-4c14-4e82-ac63-cdf9ab8e4b21", "kernelId": "", "source_hidden": false} jupyter={"outputs_hidden": false}
clean_df.to_csv('finess-clean.csv', encoding='utf-8')
# %%

104
scripts/finess-sisa.py Normal file
View File

@ -0,0 +1,104 @@
# import pandas with shortcut 'pd'
import pandas as pd
import os
from pyproj import Transformer, transform
transformer = Transformer.from_crs(2154, 4326)
headers = [
'section',
'nofinesset',
'nofinessej',
'rs',
'rslongue',
'complrs',
'compldistrib',
'numvoie',
'typvoie',
'voie',
'compvoie',
'lieuditbp',
'commune',
'departement',
'libdepartement',
'ligneacheminement',
'telephone',
'telecopie',
'categetab',
'libcategetab',
'categagretab',
'libcategagretab',
'siret',
'codeape',
'codemft',
'libmft',
'codesph',
'libsph',
'dateouv',
'dateautor',
'maj',
'numuai',
'coordxet',
'coordyet',
'sourcecoordet',
'datemaj'
]
# read_csv function which is used to read the required CSV file
data = pd.read_csv('./finess-clean.csv', sep=",", dtype='str', names=headers)
# display
#print("Original 'input.csv' CSV Data: \n")
#print(data)
header_drop = [
'section',
# 'nofinesset',
'nofinessej',
#'rs',
#'rslongue',
'complrs',
'compldistrib',
'numvoie',
'typvoie',
'voie',
'compvoie',
'lieuditbp',
'commune',
#'departement',
'libdepartement',
#'ligneacheminement',
#'telephone',
'telecopie',
#'categetab',
'libcategetab',
'categagretab',
'libcategagretab',
#'siret',
'codeape',
'codemft',
'libmft',
'codesph',
'libsph',
'dateouv',
'dateautor',
'maj',
'numuai',
#'coordxet',
#'coordyet',
'sourcecoordet',
'datemaj'
]
data = data.query('categetab == "603" or categetab == "620"')
# drop function which is used in removing or deleting rows or columns from the CSV files
data.drop(header_drop, inplace=True, axis=1)
def convertCoord (row):
row.coordxet, row.coordyet = transformer.transform(row.coordxet, row.coordyet)
return row
data.transform(convertCoord, axis=1)
data.to_json('../static/data.json', orient='values') #https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html?highlight=to_json#pandas.DataFrame.to_json

View File

@ -0,0 +1,27 @@
import { Directus } from '@directus/sdk';
import fs from 'fs';
const directus_url = "https://formulaire.p4pillon.org"
const directus = new Directus(directus_url);
async function getMspInfo() {
const response = await directus.items('MSP_INFO').readByQuery({ sort: ['nofinesset']});
return response.data
}
const mspInfo = await getMspInfo();
const data = {}
for (const msp of mspInfo) {
const nofinesset = msp.nofinesset
const info = msp
delete msp.nofinesset
data[nofinesset] = [
msp.nom,
msp.prenom_leader,
msp.nom_leader,
msp.avec_sante,
msp.accord_conventionnel_interprofessionnel,
];
}
fs.writeFileSync('../../static/data_p4pillon.json', JSON.stringify(data, null, 2) , 'utf-8');

View File

@ -0,0 +1,178 @@
{
"name": "directus-to-markdown",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "directus-to-markdown",
"version": "0.0.0",
"dependencies": {
"@directus/sdk": "^10.3.1"
}
},
"../../themes/hugo-theme-lowtech/node_modules/@resilien/directus-to-markdown": {
"extraneous": true
},
"../../themes/hugo-theme-lowtech/node_modules/url-slug": {
"extraneous": true
},
"node_modules/@directus/sdk": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/@directus/sdk/-/sdk-10.3.1.tgz",
"integrity": "sha512-+FUs1kQ27dmrHbAxO+FmCmmAHZrzyyZn+cXZMCtixkeBD8KYBFM7sUKtesQskSmsp5wUksrq2L9Cm+Z93G/ONg==",
"dependencies": {
"axios": "^0.27.2"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"dependencies": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
}
},
"dependencies": {
"@directus/sdk": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/@directus/sdk/-/sdk-10.3.1.tgz",
"integrity": "sha512-+FUs1kQ27dmrHbAxO+FmCmmAHZrzyyZn+cXZMCtixkeBD8KYBFM7sUKtesQskSmsp5wUksrq2L9Cm+Z93G/ONg==",
"requires": {
"axios": "^0.27.2"
}
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"requires": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"requires": {
"mime-db": "1.52.0"
}
}
}
}

View File

@ -0,0 +1,10 @@
{
"name": "annuaire-p4pillon",
"version": "0.0.0",
"description": "Import Directus.io to gohugo.io",
"main": "index.js",
"type": "module",
"dependencies": {
"@directus/sdk": "^10.3.1"
}
}

3
scripts/requirements.txt Normal file
View File

@ -0,0 +1,3 @@
pandas==1.5.0
requests==2.28.1
pyproj==3.4.0

1
static/data.json Normal file

File diff suppressed because one or more lines are too long

44
static/data_p4pillon.json Normal file
View File

@ -0,0 +1,44 @@
{
"190012278": [
"MSP du pays acadien ",
"Benjamin",
"LECAVELIER",
true,
null
],
"190012294": [
"MSP lubersac projet pompadour",
"Maryline",
"DUMONT",
null,
true
],
"190012427": [
"PSP Millesoins",
"Antoine",
"PRIOUX",
true,
true
],
"190012443": [
"Pole de santé de Haute-Corrèze",
"Cyril",
"MOESCH",
null,
null
],
"190013144": [
"Maison de Santé des Eaux Vives",
"Anaïs",
"CARTEGNIE",
true,
true
],
"190013805": [
"MSP MANSAC",
"Hélène",
"SCHWARTZ",
false,
null
]
}

View File

@ -0,0 +1,56 @@
L.Permalink = {
//gets the map center, zoom-level and rotation from the URL if present, else uses default values
getMapLocation: function (zoom, center) {
'use strict';
zoom = (zoom || zoom === 0) ? zoom : 18;
center = (center) ? center : [52.26869, -113.81034];
if (window.location.hash !== '') {
var hash = window.location.hash.replace('#', '');
var parts = hash.split(',');
if (parts.length === 3) {
center = {
lat: parseFloat(parts[0]),
lng: parseFloat(parts[1])
};
zoom = parseInt(parts[2].slice(0, -1), 10);
}
}
return {zoom: zoom, center: center};
},
setup: function (map) {
'use strict';
var shouldUpdate = true;
var updatePermalink = function () {
if (!shouldUpdate) {
// do not update the URL when the view was changed in the 'popstate' handler (browser history navigation)
shouldUpdate = true;
return;
}
var center = map.getCenter();
var hash = '#' +
Math.round(center.lat * 100000) / 100000 + ',' +
Math.round(center.lng * 100000) / 100000 + ',' +
map.getZoom() + 'z';
var state = {
zoom: map.getZoom(),
center: center
};
window.history.pushState(state, 'map', hash);
};
map.on('moveend', updatePermalink);
// restore the view state when navigating through the history, see
// https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
window.addEventListener('popstate', function (event) {
if (event.state === null) {
return;
}
map.setView(event.state.center, event.state.zoom);
shouldUpdate = false;
});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
static/p4pillon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

4
static/pharmacy_alt.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.8708 16.5029L26.5001 16.5029C27.0523 16.5029 27.5001 16.0552 27.5001 15.5029C27.5001 14.9506 27.0523 14.5029 26.5001 14.5029L23.8708 14.5029C23.5214 14.503 23.1149 14.56 22.7209 14.7523C21.2959 15.4476 20.4893 16.6497 20.0467 17.8209C19.8971 18.2165 19.786 18.6158 19.7045 19.0029H21.7622C21.8068 18.8436 21.8583 18.6846 21.9175 18.528C22.2394 17.6764 22.7625 16.9573 23.5979 16.5497C23.6444 16.527 23.7301 16.5029 23.8708 16.5029ZM18.0001 20.0029C17.4478 20.0029 16.9874 20.4588 17.1366 20.9906C17.7143 23.05 20.0631 24.6522 23.0001 24.9523V26.5105C22.3051 26.5275 21.5829 26.5829 20.9705 26.7612C20.492 26.9005 19.9849 27.1393 19.5969 27.575C19.1907 28.0312 19 28.6074 19 29.25C19 29.8932 19.1902 30.47 19.5958 30.9272C19.9836 31.3641 20.4906 31.6038 20.9696 31.7437C21.2897 31.8372 21.6397 31.897 22 31.9353V29.9217C21.8289 29.8972 21.6722 29.8653 21.5305 29.8239C21.2595 29.7448 21.1415 29.6558 21.0918 29.5997C21.0599 29.5638 21 29.4833 21 29.25C21 29.0191 21.0594 28.9401 21.0907 28.905C21.1402 28.8493 21.2581 28.7605 21.5296 28.6814C21.9135 28.5697 22.4074 28.5277 23.0001 28.5121V29.9938L23 31.9954L23.0001 34.0029H20.0001V36.0029H28.0001V34.0029H25.0001V28.4661C26.1018 28.3797 26.9948 28.1376 27.6667 27.7046C28.6123 27.0953 29 26.1881 29 25.2252C29 24.7019 28.8853 24.199 28.6292 23.7536C29.754 23.0448 30.5574 22.0819 30.8635 20.9906C31.0127 20.4588 30.5523 20.0029 30.0001 20.0029H18.0001ZM26.5833 26.0235C26.3 26.2061 25.8089 26.3795 25.0001 26.4584V24.9523C25.6205 24.8889 26.2147 24.7674 26.7715 24.5957C26.9363 24.7528 27 24.9436 27 25.2252C27 25.5956 26.8878 25.8272 26.5833 26.0235Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32 32H42V16H32V6H16V16H6V32H16V42H32V32ZM30 40V30H40V18H30V8H18V18H8V30H18V40H30Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

5
static/village.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.4453 6.16795C16.7812 5.94402 17.2188 5.94402 17.5547 6.16795L23.5547 10.1679C23.8329 10.3534 24 10.6656 24 11V19C24 19.5523 23.5523 20 23 20H11C10.4477 20 10 19.5523 10 19V11C10 10.6656 10.1671 10.3534 10.4453 10.1679L16.4453 6.16795ZM16 18H18V14H16V18ZM20 18V13C20 12.4477 19.5523 12 19 12H15C14.4477 12 14 12.4477 14 13V18H12V11.5352L17 8.20185L22 11.5352V18H20Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.4961 12.1318C34.1887 11.9561 33.8113 11.9561 33.5039 12.1318L26.5039 16.1318C26.1923 16.3098 26 16.6411 26 17V27C26 27.5523 26.4477 28 27 28H41C41.5523 28 42 27.5523 42 27V17C42 16.6411 41.8077 16.3098 41.4961 16.1318L34.4961 12.1318ZM37 26H40V17.5803L34 14.1518L28 17.5803V26H31V20C31 19.4477 31.4477 19 32 19H36C36.5523 19 37 19.4477 37 20V26ZM35 26V21H33V26H35Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.4472 28.1056L15.4472 24.1056C15.1657 23.9648 14.8343 23.9648 14.5528 24.1056L6.55279 28.1056C6.214 28.275 6 28.6212 6 29V41C6 41.5523 6.44772 42 7 42H23C23.5523 42 24 41.5523 24 41V29C24 28.6212 23.786 28.275 23.4472 28.1056ZM16 34V40H14V34H16ZM18 33V40H22V29.618L15 26.118L8 29.618V40H12V33C12 32.4477 12.4477 32 13 32H17C17.5523 32 18 32.4477 18 33Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

23
tailwind.config.js Normal file
View File

@ -0,0 +1,23 @@
const typography = require('@tailwindcss/typography');
const forms = require('@tailwindcss/forms');
module.exports = {
content: ['./hugo_stats.json'],
// safelist: [
// {
// pattern: /./, // the "." means "everything"
// },
// ],
plugins: [
typography,
forms,
],
// theme: {
// extend: {
// ringColor: ({ theme }) => ({
// DEFAULT: theme('colors.green.700', '#3b82f6'),
// ...theme('colors'),
// }),
// }
// }
};