431 lines
15 KiB
JavaScript
431 lines
15 KiB
JavaScript
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;
|