SEND all files + questionnaires + json + data_tests
This commit is contained in:
24
src/App.css
Normal file
24
src/App.css
Normal file
@@ -0,0 +1,24 @@
|
||||
.App {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App em {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.App header {
|
||||
padding-top: 45px;
|
||||
}
|
||||
|
||||
.App footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
|
||||
431
src/App.js
Normal file
431
src/App.js
Normal file
@@ -0,0 +1,431 @@
|
||||
import React, {Component} from 'react';
|
||||
import ProgressBox from './ProgressBox';
|
||||
import QuestionBox from './QuestionBox';
|
||||
// import './App.css';
|
||||
import 'material-design-icons-iconfont/dist/material-design-icons.css';
|
||||
|
||||
|
||||
class App extends Component {
|
||||
state = {
|
||||
config: null,
|
||||
question: null,
|
||||
answers: [],
|
||||
message: '',
|
||||
isLastQuestion: false,
|
||||
currentQuestionIndex: 0,
|
||||
directories: [],
|
||||
uniqueIdInput: ''
|
||||
};
|
||||
|
||||
api = {
|
||||
showMessage: (message) => {
|
||||
this.setState({ message });
|
||||
},
|
||||
updateState: (newState) => {
|
||||
this.setState(newState);
|
||||
}
|
||||
};
|
||||
|
||||
handleUniqueIdChange = (event) => {
|
||||
this.setState({ uniqueIdInput: event.target.value });
|
||||
};
|
||||
|
||||
handleUniqueIdSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
this.getAnswers(this.state.uniqueIdInput);
|
||||
};
|
||||
|
||||
|
||||
/// SI /?id=eddd
|
||||
/// ( sans /test_sub_name/?id=eddd -> récupérer currentPath à partir de l'id )
|
||||
getAnswers = async (uniqueId) => {
|
||||
const url = `/api/getanswers/`;
|
||||
|
||||
const headers = Object.assign(
|
||||
{'Content-Type': 'application/json', 'X-Unique-ID': uniqueId},
|
||||
{}
|
||||
);
|
||||
|
||||
console.error(uniqueId)
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
});
|
||||
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`HTTP error! status: ${response.status}`);
|
||||
// }
|
||||
|
||||
|
||||
const data = await response.json();
|
||||
const find_questionnaire_path=data[0].currentPath
|
||||
console.log('---- Données reçues (async getAnswers) :\n', data);
|
||||
console.log(find_questionnaire_path)
|
||||
|
||||
window.location.href = window.location.origin + find_questionnaire_path + "?id=" + uniqueId;
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la récupération des réponses :', error);
|
||||
this.api.showMessage('Erreur lors de la récupération des réponses Vérifier l\'identifiant unique.');
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
const currentPath = window.location.pathname;
|
||||
console.log(currentPath);
|
||||
|
||||
let config;
|
||||
let jsonData;
|
||||
try {
|
||||
if (currentPath === "/") {
|
||||
config = require('./questionnaires/Questionful.json');
|
||||
// this.api.showMessage('GO');
|
||||
|
||||
/// SI /?id=eddd
|
||||
/// ( sans /test_sub_name/?id=eddd -> récupérer currentPath à partir de l'id )
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const idParam = searchParams.get('id');
|
||||
if (idParam) {
|
||||
this.getAnswers(idParam);
|
||||
}
|
||||
|
||||
} else {
|
||||
config = require('./questionnaires' + currentPath + '/Questionful.json');
|
||||
|
||||
const pathSegments = currentPath.split('/').filter(segment => segment !== '');
|
||||
const lastSegment = pathSegments[pathSegments.length - 1] || 'Accueil';
|
||||
document.title = lastSegment.charAt(0).toUpperCase() + lastSegment.slice(1) + " ( questionnaire )";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Erreur lors du chargement de la configuration :", error);
|
||||
this.api.showMessage('Error! Failed to load configuration.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ config }, () => {
|
||||
if (!this.state.config) {
|
||||
this.api.showMessage('Error! No configuration provided.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Récupérer l'uniqueId depuis config
|
||||
const { uniqueId } = this.state.config;
|
||||
console.log("// uniqueId "+uniqueId) ///// undefined !
|
||||
// //// not set in config, saved in data.json THEN user client parameter
|
||||
|
||||
|
||||
// const searchParams = new URLSearchParams(window.location.search);
|
||||
// const idParam = searchParams.get('id');
|
||||
// const uniqueId_state = idParam;
|
||||
// const questionParam = searchParams.get('question');
|
||||
// console.log("uniqueId_state // "+uniqueId_state)
|
||||
// if (idParam) {
|
||||
// jsonData = require('./data.json');
|
||||
// const filteredData = jsonData.filter(item => item.uniqueId === uniqueId_state);
|
||||
// if (filteredData.length === 0) {
|
||||
// console.error(`Aucune entrée trouvée avec l'uniqueId: ${uniqueId}`);
|
||||
// // return res.status(404).send('Aucune donnée trouvée pour cet identifiant unique.');
|
||||
// } else {
|
||||
// console.warn("// uniqueId filteredData OK (read, loaded)")
|
||||
// // console.warn(filteredData)
|
||||
// // return filteredData
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// Si uniqueId existe, récupérer les réponses
|
||||
if (uniqueId) { /// This works ? using api server ?
|
||||
alert("getone")
|
||||
this.getAnswers(uniqueId);
|
||||
}
|
||||
|
||||
if (!this.state.question) {
|
||||
this.api.updateState({ question: this.state.config.questions[0] });
|
||||
}
|
||||
|
||||
// Mettre à jour les variables CSS
|
||||
this.updateCssVariables();
|
||||
});
|
||||
|
||||
if (currentPath === "/") {
|
||||
this.fetchDirectories();
|
||||
} else {
|
||||
|
||||
|
||||
// Création de la boîte d'information
|
||||
const infoBox = document.createElement('div');
|
||||
infoBox.id = 'info-box';
|
||||
infoBox.innerHTML = `
|
||||
<div id="info-toggle">
|
||||
<label>
|
||||
<input type="checkbox" id="toggle-display"> <span id="toggle_hide_text">Masquer</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="info-content">
|
||||
<div><strong>Parent :</strong> <span id="element-parent"></span></div>
|
||||
<div><strong>Enfant :</strong> <span id="element-info"></span></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Ajout des styles
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
#info-box {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
background: #333;
|
||||
color: white;
|
||||
padding: 10px 11px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
min-width: 250px;
|
||||
max-width: 250px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
|
||||
font-size: 14px;
|
||||
display: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#info-box.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#info-box div {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
#info-box strong {
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
#info-toggle {
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #555;
|
||||
}
|
||||
|
||||
#info-box.no_infos {
|
||||
max-width: 200px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
#info-box.no_infos {
|
||||
#info-toggle {
|
||||
border-bottom: 0px solid #555;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#toggle_hide_text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
#info-toggle label {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#info-content.hidden {
|
||||
display: none;
|
||||
}
|
||||
.info_id {
|
||||
color: #ff0095;
|
||||
}
|
||||
.info_class {
|
||||
color:rgb(0, 200, 215);
|
||||
}
|
||||
.info_el {
|
||||
color:rgb(0, 179, 255);
|
||||
}
|
||||
.info_prop {
|
||||
margin-right: 2px;
|
||||
}
|
||||
`;
|
||||
|
||||
// Injection dans le DOM
|
||||
document.head.appendChild(style);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
updateCssVariables = () => {
|
||||
const { config } = this.state;
|
||||
if (!config || !config.styles) return;
|
||||
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--background-color', config.styles.backgroundColor);
|
||||
root.style.setProperty('--primary-color', config.styles.primaryColor);
|
||||
root.style.setProperty('--secondary-color', config.styles.secondaryColor);
|
||||
root.style.setProperty('--secondary-altcolor', config.styles.secondaryAltColor);
|
||||
};
|
||||
|
||||
fetchDirectories = () => {
|
||||
fetch('/api/list-codes')
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur HTTP : ${response.status}`);
|
||||
}
|
||||
return response.text().then(text => {
|
||||
console.log('Réponse brute de l\'API :', text);
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.error('Erreur de parsing JSON :', e);
|
||||
throw new Error('La réponse n\'est pas un JSON valide');
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
this.setState({ directories: data.directories });
|
||||
} else {
|
||||
console.error('Erreur :', data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erreur lors de la récupération des dossiers :', error);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { config, question, answers, message, isLastQuestion, currentQuestionIndex, directories } = this.state;
|
||||
const currentPath = window.location.pathname;
|
||||
|
||||
if (!config) {
|
||||
return <div>Chargement de la configuration...</div>;
|
||||
}
|
||||
|
||||
const props = {
|
||||
state: this.state,
|
||||
api: this.api
|
||||
};
|
||||
|
||||
const appStyle = {
|
||||
background: config.styles.backgroundColor,
|
||||
color: config.styles.primaryFontColor,
|
||||
fontFamily: config.styles.fontFamily
|
||||
};
|
||||
|
||||
const footerStyle = {
|
||||
color: config.styles.secondaryFontColor
|
||||
};
|
||||
|
||||
const inputStyle = {
|
||||
padding: '8px',
|
||||
marginRight: '10px',
|
||||
borderRadius: '4px',
|
||||
border: '1px solid #ccc'
|
||||
};
|
||||
|
||||
const buttonStyle = {
|
||||
padding: '8px 16px',
|
||||
backgroundColor: '#007bff',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer'
|
||||
};
|
||||
|
||||
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const idParam = searchParams.get('id');
|
||||
const idQuest = searchParams.get('question');
|
||||
let hide_p = (idParam) ? "have_id" : "no_id";
|
||||
let hide_part = (idQuest) ? hide_p+ " have_quest" : hide_p+ " no_quest";
|
||||
|
||||
if (currentPath !== "/") {
|
||||
|
||||
|
||||
return (
|
||||
<div className="App" data-have-id={hide_part} style={appStyle}>
|
||||
{/* <a href="/"><img class='icon small' src='questionful.png' /></a> */}
|
||||
<header>
|
||||
<ProgressBox {...props} />
|
||||
</header>
|
||||
<em id="message_message">{message}</em>
|
||||
<QuestionBox {...props} />
|
||||
<div id="answersDataContainer" className="resp_background">
|
||||
{/* Exemple d'affichage des réponses */}
|
||||
{/* {answers.length > 0 && (
|
||||
<div>
|
||||
<h3>Réponses précédentes :</h3>
|
||||
<ul>
|
||||
{answers.map((answer, index) => (
|
||||
<li key={index}>{answer.text}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)} */}
|
||||
</div>
|
||||
<footer style={footerStyle}>
|
||||
{/* <div class="copy-notification"></div> */}
|
||||
{/* Copyright © {(new Date()).getFullYear()} */}
|
||||
{/* - */}
|
||||
{/* <a href="https://alextselegidis.com" target="_blank" style={footerStyle}>Alex Tselegidis</a> */}
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
} else { /// HOME
|
||||
|
||||
return (
|
||||
<div className="App" style={appStyle}>
|
||||
<header>
|
||||
{/* <ProgressBox {...props} /> */}
|
||||
</header>
|
||||
|
||||
<h1 id="home_title"><img class='icon large' src='questionful.png' />Questionnaires</h1>
|
||||
<em id="message_message">{message}</em>
|
||||
<div id="wrapper_home">
|
||||
{/* <h2 id="home_list_dirs">Dossiers disponibles :</h2> */}
|
||||
<ul>
|
||||
{directories.map((directory, index) => (
|
||||
<li key={index}>
|
||||
<a href={directory.name}>{directory.name}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="unique-id-section">
|
||||
<h3 className="unique-id-title">Récupérer vos réponses avec votre ID unique</h3>
|
||||
<div>
|
||||
<strong>( généré lors de la dernière question-réponse )<br />( penser à le noter / sauvegarder )</strong>
|
||||
</div>
|
||||
<form onSubmit={this.handleUniqueIdSubmit}>
|
||||
<input
|
||||
id="uniqueidinput"
|
||||
type="text"
|
||||
placeholder="Entrez un ID unique"
|
||||
value={this.state.uniqueIdInput}
|
||||
onChange={this.handleUniqueIdChange}
|
||||
style={inputStyle}
|
||||
/>
|
||||
<br />
|
||||
<button type="submit" style={buttonStyle}>Récupérer les réponses</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<footer style={footerStyle}>
|
||||
|
||||
{/*Copyright © {(new Date()).getFullYear()}
|
||||
-
|
||||
<a href="https://alextselegidis.com" target="_blank" style={footerStyle}>Alex Tselegidis</a>*/}
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
} /// if /HOME ?
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
11
src/ProgressBox.css
Normal file
11
src/ProgressBox.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.ProgressBox {
|
||||
margin-bottom: 45px;
|
||||
}
|
||||
|
||||
.ProgressBox h1 {
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.ProgressBox h1 strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
48
src/ProgressBox.js
Normal file
48
src/ProgressBox.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import React, {Component} from 'react';
|
||||
import './ProgressBox.css';
|
||||
const currentPath= window.location.pathname;
|
||||
|
||||
|
||||
class ProgressBox extends Component {
|
||||
|
||||
render() {
|
||||
const index = !this.props.state.question ? this.props.state.currentQuestionIndex : this.props.state.currentQuestionIndex + 1;
|
||||
|
||||
const style = {
|
||||
color: this.props.state.config.styles.secondaryFontColor
|
||||
};
|
||||
|
||||
|
||||
const searchParams= new URLSearchParams(window.location.search);
|
||||
const paramid =searchParams.get('id')
|
||||
|
||||
|
||||
return (
|
||||
<div className="ProgressBox" style={style}>
|
||||
<a href="/" id="home"><img className='icon small' src='questionful.png' />
|
||||
/
|
||||
</a>
|
||||
<div id="test_titre">
|
||||
<a href={currentPath}>
|
||||
{currentPath.replace("/","")}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h1 className="ProgressBox_title">
|
||||
<span id="Progress_question">Question </span><span id="progress_nums"><strong>{index-1}</strong> sur <strong>{this.props.state.config.questions.length-1}</strong></span>
|
||||
</h1>
|
||||
|
||||
|
||||
{paramid && paramid !== "" && (
|
||||
<h1 className="paramid">
|
||||
{paramid}
|
||||
</h1>
|
||||
)}
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ProgressBox;
|
||||
37
src/QuestionBox.css
Normal file
37
src/QuestionBox.css
Normal file
@@ -0,0 +1,37 @@
|
||||
.QuestionBox h1 {
|
||||
margin-bottom: 45px;
|
||||
text-shadow: 7px 5px 12px #00000052;
|
||||
}
|
||||
|
||||
.QuestionBox input {
|
||||
display: block;
|
||||
background: none;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid;
|
||||
width: 85%;
|
||||
max-width: 750px;
|
||||
padding: 15px;
|
||||
margin-bottom: 30px;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto 45px auto;
|
||||
}
|
||||
|
||||
.QuestionBox input:active,
|
||||
.QuestionBox input:focus {
|
||||
background: #00000014;
|
||||
}
|
||||
|
||||
.QuestionBox button {
|
||||
background: none;
|
||||
border: 1px solid;
|
||||
padding: 15px 30px;
|
||||
min-width: 200px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.QuestionBox button:hover {
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
2093
src/QuestionBox.js
Normal file
2093
src/QuestionBox.js
Normal file
File diff suppressed because it is too large
Load Diff
2817
src/data.json
Normal file
2817
src/data.json
Normal file
File diff suppressed because it is too large
Load Diff
24
src/index.css
Normal file
24
src/index.css
Normal file
@@ -0,0 +1,24 @@
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
body * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
8
src/index.js
Normal file
8
src/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
// process.title = 'questionful';
|
||||
ReactDOM.render(<App/>, document.getElementById('root'));
|
||||
registerServiceWorker();
|
||||
53
src/questionnaires/Questionful.json
Normal file
53
src/questionnaires/Questionful.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"title": "Questionful",
|
||||
"submission": {
|
||||
"url": "/api/submit",
|
||||
"headers": {}
|
||||
},
|
||||
"getAnswers": {
|
||||
"url": "/api/getanswers",
|
||||
"headers": {}
|
||||
},
|
||||
"list_codes": {
|
||||
"url": "/api/list-codes",
|
||||
"headers": {}
|
||||
},
|
||||
"styles": {
|
||||
"backgroundColor": "#FFF",
|
||||
"primaryColor": "#000",
|
||||
"secondaryColor": "darkcyan",
|
||||
"secondaryAltColor": "cyan",
|
||||
"fontFamily": "'Open Sans', Helvetica, Arial, sans-serif"
|
||||
},
|
||||
"questions": [
|
||||
{
|
||||
"id": "name",
|
||||
"title": "name?",
|
||||
"code": [
|
||||
{
|
||||
"file": "css.css",
|
||||
"type": "css"
|
||||
},
|
||||
{
|
||||
"file": "core.page",
|
||||
"type": "markup",
|
||||
"para": "nohelp"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "age ss",
|
||||
"title": "What is your age ss ?",
|
||||
"code": [
|
||||
{
|
||||
"file": "css.css",
|
||||
"type": "css"
|
||||
},
|
||||
{
|
||||
"file": "age.html",
|
||||
"type": "markup"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
276
src/questionnaires/all/Questionful.json
Normal file
276
src/questionnaires/all/Questionful.json
Normal file
@@ -0,0 +1,276 @@
|
||||
{
|
||||
"title": "Questionful",
|
||||
"folde": "all",
|
||||
|
||||
"questions": [
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "tuto",
|
||||
"title": "Tuto, explications sur le questionnaire",
|
||||
"para": "normal",
|
||||
"explo":"Courte description",
|
||||
"short":"comment ça marche",
|
||||
"code": [
|
||||
{
|
||||
"file": "tuto.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "tuto.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "tuto.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_id_classes_multiples",
|
||||
"title": "CSS, cibler un élément avec une classe / des classes",
|
||||
"para": "normal",
|
||||
"explo":"Ciblage simple",
|
||||
"short":"simple -- id + class",
|
||||
"code": [
|
||||
{
|
||||
"file": "cibler_id_classes_multiples.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_id_classes_multiples.css",
|
||||
"type": "css",
|
||||
"para": "large"
|
||||
},
|
||||
{
|
||||
"file": "cibler_id_classes_multiples.page",
|
||||
"type": "markup",
|
||||
"para": "large locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "cibler_css_multiples_vs_is",
|
||||
"title": "CSS, ciblage multiple, /VS/ condition :is ",
|
||||
"short": "été automne",
|
||||
"para": "normal",
|
||||
"explo":"* joker + :is",
|
||||
"code": [
|
||||
|
||||
{
|
||||
"file": "cibler_css_multiples_vs_is.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_multiples_vs_is.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_multiples_vs_is.page",
|
||||
"type": "markup",
|
||||
"para": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "cibler_css_padding",
|
||||
"title": "CSS, modifier les marges internes",
|
||||
"para": "normal",
|
||||
"explo": "margin == marges extérieures ; padding == marges internes",
|
||||
"short":"padding",
|
||||
"code": [
|
||||
|
||||
{
|
||||
"file": "cibler_css_padding.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_padding.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_padding.page",
|
||||
"type": "markup",
|
||||
"para": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_css_margin_transition",
|
||||
"title": "CSS, margin + transition + :hover + --variable",
|
||||
"para": "normal",
|
||||
"explo": "transition : propriété_afectée durée élasticité_animation délais",
|
||||
"short":"bouge de là",
|
||||
"code": [
|
||||
|
||||
{
|
||||
"file": "cibler_css_margin_transition.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_margin_transition.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_css_margin_transition.page",
|
||||
"type": "markup",
|
||||
"para": "locked"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_is_not",
|
||||
"title": "CSS :is :not :has + attributs",
|
||||
"para": "normal",
|
||||
"short": "working state",
|
||||
"code": [
|
||||
{
|
||||
"file": "cibler_is_not.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_is_not.css",
|
||||
"type": "css",
|
||||
"para": "large"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "cibler_is_not.page",
|
||||
"type": "markup",
|
||||
"para": "large force_sticky"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_adjascent_avance",
|
||||
"title": "CSS, cibler des éléments adjascents, internes ou suivants",
|
||||
"para": "normal",
|
||||
"short":":hover Miaous !",
|
||||
"code": [
|
||||
|
||||
{
|
||||
"file": "cibler_adjascent_avance.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
{
|
||||
"file": "cibler_adjascent_avance.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "cibler_adjascent_avance.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_has_checked",
|
||||
"title": "CSS :has :checked :active",
|
||||
"para": "normal",
|
||||
"short":"fôret champignons",
|
||||
"code": [
|
||||
{
|
||||
"file": "cibler_has_checked.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
{
|
||||
"file": "cibler_has_checked.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "cibler_has_checked.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
],
|
||||
|
||||
"submission": {
|
||||
"url": "/api/submit",
|
||||
"headers": {}
|
||||
},
|
||||
"getAnswers": {
|
||||
"url": "/api/getanswers",
|
||||
"headers": {}
|
||||
},
|
||||
"savefile": {
|
||||
"url": "/api/savefile",
|
||||
"headers": {}
|
||||
},
|
||||
"getResults": {
|
||||
"url": "/api/getresults",
|
||||
"headers": {}
|
||||
},
|
||||
"list_codes": {
|
||||
"url": "/api/list-codes",
|
||||
"headers": {}
|
||||
},
|
||||
"styles": {
|
||||
"backgroundColor": "#FFF",
|
||||
"primaryColor": "#000",
|
||||
"secondaryColor": "darkcyan",
|
||||
"secondaryAltColor": "cyan",
|
||||
"fontFamily": "'Open Sans', Helvetica, Arial, sans-serif"
|
||||
}
|
||||
}
|
||||
67
src/questionnaires/cibler_css_id_class_menu/Questionful.json
Normal file
67
src/questionnaires/cibler_css_id_class_menu/Questionful.json
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
{
|
||||
"title": "Questionful",
|
||||
"folde": "cibler_css_id_class_menu",
|
||||
|
||||
"questions": [
|
||||
|
||||
|
||||
{
|
||||
"id": "cibler_css_id_class_menu",
|
||||
"title": "CSS, cibler, element, id, class, attribut",
|
||||
"para": "normal",
|
||||
"short": "menu attributs",
|
||||
"code": [
|
||||
|
||||
{
|
||||
"file": "cibler_css_id_class_menu.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp"
|
||||
},
|
||||
{
|
||||
"file": "cibler_css_id_class_menu.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "cibler_css_id_class_menu.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
],
|
||||
|
||||
"submission": {
|
||||
"url": "/api/submit",
|
||||
"headers": {}
|
||||
},
|
||||
"getAnswers": {
|
||||
"url": "/api/getanswers",
|
||||
"headers": {}
|
||||
},
|
||||
"savefile": {
|
||||
"url": "/api/savefile",
|
||||
"headers": {}
|
||||
},
|
||||
"getResults": {
|
||||
"url": "/api/getresults",
|
||||
"headers": {}
|
||||
},
|
||||
"list_codes": {
|
||||
"url": "/api/list-codes",
|
||||
"headers": {}
|
||||
},
|
||||
"styles": {
|
||||
"backgroundColor": "#FFF",
|
||||
"primaryColor": "#000",
|
||||
"secondaryColor": "darkcyan",
|
||||
"secondaryAltColor": "cyan",
|
||||
"fontFamily": "'Open Sans', Helvetica, Arial, sans-serif"
|
||||
}
|
||||
}
|
||||
|
||||
127
src/questionnaires/html/Questionful.json
Normal file
127
src/questionnaires/html/Questionful.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"title": "Questionful",
|
||||
"folde": "html",
|
||||
|
||||
"questions": [
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "tuto_html",
|
||||
"title": "class id ( + parent -> enfant )",
|
||||
"para": "normal",
|
||||
"explo":"",
|
||||
"short":"id / class / ' '",
|
||||
"code": [
|
||||
{
|
||||
"file": "tuto_html.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "tuto_html.css",
|
||||
"type": "css",
|
||||
"para": "large locked"
|
||||
},
|
||||
{
|
||||
"file": "tuto_html.page",
|
||||
"type": "markup",
|
||||
"para": "large"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "sauts_de_lignes",
|
||||
"title": "Sauts de ligne",
|
||||
"para": "normal",
|
||||
"explo":"",
|
||||
"short":"<br /> <hr /> + <img />",
|
||||
"code": [
|
||||
{
|
||||
"file": "sauts_de_lignes.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "sauts_de_lignes.css",
|
||||
"type": "css",
|
||||
"para": "large locked"
|
||||
},
|
||||
{
|
||||
"file": "sauts_de_lignes.page",
|
||||
"type": "markup",
|
||||
"para": "large"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "class_id_child",
|
||||
"title": "class id ( + parent -> enfant )",
|
||||
"para": "normal",
|
||||
"explo":"",
|
||||
"short":"id / class / ' '",
|
||||
"code": [
|
||||
{
|
||||
"file": "class_id_child.txt",
|
||||
"type": "render",
|
||||
"para": "large instructions nohelp locked"
|
||||
},
|
||||
|
||||
{
|
||||
"file": "class_id_child.css",
|
||||
"type": "css",
|
||||
"para": "large locked"
|
||||
},
|
||||
{
|
||||
"file": "class_id_child.page",
|
||||
"type": "markup",
|
||||
"para": "large"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
],
|
||||
|
||||
"submission": {
|
||||
"url": "/api/submit",
|
||||
"headers": {}
|
||||
},
|
||||
"getAnswers": {
|
||||
"url": "/api/getanswers",
|
||||
"headers": {}
|
||||
},
|
||||
"savefile": {
|
||||
"url": "/api/savefile",
|
||||
"headers": {}
|
||||
},
|
||||
"getResults": {
|
||||
"url": "/api/getresults",
|
||||
"headers": {}
|
||||
},
|
||||
"list_codes": {
|
||||
"url": "/api/list-codes",
|
||||
"headers": {}
|
||||
},
|
||||
"styles": {
|
||||
"backgroundColor": "#FFF",
|
||||
"primaryColor": "#000",
|
||||
"secondaryColor": "darkcyan",
|
||||
"secondaryAltColor": "cyan",
|
||||
"fontFamily": "'Open Sans', Helvetica, Arial, sans-serif"
|
||||
}
|
||||
}
|
||||
77
src/questionnaires/one/Questionful.json
Normal file
77
src/questionnaires/one/Questionful.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"title": "Questionful",
|
||||
"folde": "one",
|
||||
|
||||
"questions": [
|
||||
|
||||
{
|
||||
"id": "red",
|
||||
"title": "test",
|
||||
"para": "normal",
|
||||
"explo":"",
|
||||
"code": [
|
||||
{
|
||||
"file": "red.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "red.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "blue",
|
||||
"title": "test",
|
||||
"para": "normal",
|
||||
"explo":"",
|
||||
"code": [
|
||||
{
|
||||
"file": "blue.css",
|
||||
"type": "css",
|
||||
"para": ""
|
||||
},
|
||||
{
|
||||
"file": "blue.page",
|
||||
"type": "markup",
|
||||
"para": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
],
|
||||
|
||||
"submission": {
|
||||
"url": "/api/submit",
|
||||
"headers": {}
|
||||
},
|
||||
"getAnswers": {
|
||||
"url": "/api/getanswers",
|
||||
"headers": {}
|
||||
},
|
||||
"savefile": {
|
||||
"url": "/api/savefile",
|
||||
"headers": {}
|
||||
},
|
||||
"getResults": {
|
||||
"url": "/api/getresults",
|
||||
"headers": {}
|
||||
},
|
||||
"list_codes": {
|
||||
"url": "/api/list-codes",
|
||||
"headers": {}
|
||||
},
|
||||
"styles": {
|
||||
"backgroundColor": "#FFF",
|
||||
"primaryColor": "#000",
|
||||
"secondaryColor": "darkcyan",
|
||||
"secondaryAltColor": "cyan",
|
||||
"fontFamily": "'Open Sans', Helvetica, Arial, sans-serif"
|
||||
}
|
||||
}
|
||||
117
src/registerServiceWorker.js
Normal file
117
src/registerServiceWorker.js
Normal file
@@ -0,0 +1,117 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user