Files
questionnaire/src/App.js

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 &copy; {(new Date()).getFullYear()} */}
{/* &nbsp;-&nbsp; */}
{/* <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 &copy; {(new Date()).getFullYear()}
&nbsp;-&nbsp;
<a href="https://alextselegidis.com" target="_blank" style={footerStyle}>Alex Tselegidis</a>*/}
</footer>
</div>
);
} /// if /HOME ?
}
}
export default App;