| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- import { h, render, Component } from 'preact'; // eslint-disable-line no-unused-vars
- // Content
- import content from '../content/module.json';
- import questions from '../content/questions.json';
- import data from '../content/offline';
- // Configuration
- import config from '../config';
- // Services
- import api from '../utilities/api';
- // Views
- import TitleScreen from './TitleScreen.jsx';
- import FinalScreen from './FinalScreen.jsx';
- import ChartScreen from './ChartScreen.jsx';
- /**
- * titlescreen -> chartscreen (*n) -> finalscreen
- */
- export default class App extends Component {
- // Initialize functions
- constructor (props) {
- super(props);
- this.state = {
- route: 'titlescreen', // Current screen
- currentQuestion: 0, // Current question
- currentStep: 0, // Current graph task
- chartMode: 'interaction', // Mode for graph 'interaction', 'presentation' or 'comparison'
- questions: [], // Wrapper for all questions
- data: [], // Global data wrapper
- interactionData: [], // Wrapper for interaction data
- comparisonData: [], // Wrapper for comparison data
- isFetching: false, // Currently performing XHR?
- userId: null, // Current user id for posting
- token: null // Current access token
- };
- // Context binding
- this.navigate = this.navigate.bind(this);
- this.toNextStep = this.toNextStep.bind(this);
- this.setup = this.setup.bind(this);
- this.setData = this.setData.bind(this);
- }
- // Initial setup, get accesToken and userId
- setup () {
- this.setState({ questions });
- if (this.props.isOffline) {
- this.setState({ data });
- } else {
- this.setState({ isFetching: true });
- api.getToken().then(accessToken => {
- this.setState({ token: accessToken });
- // Create user
- api.createUser(accessToken)
- .then(user => {
- this.setState({
- userId: user.userId,
- isFetching: false
- });
- // Draw first question
- this.drawQuestions();
- });
- });
- }
- }
- // Navigate to specific route
- navigate (route) {
- if (route !== 'titlescreen') {
- this.setState({ route });
- } else {
- location.reload();
- }
- }
- // Set data
- setData (newData) {
- this.setState({ interactionData: newData });
- }
- // Get number of questions
- getNumberQuestions () {
- let sum = 0;
- for (let i = 0; i < this.state.questions.length; i += 1) {
- sum += this.state.questions[i].length;
- }
- return sum;
- }
- // Get question set from api
- drawQuestions () {
- let newData = [ ...this.state.data ];
- api.get(config.api.lists.a)
- .then(json => {
- newData[0] = json;
- // })
- // .then(() => api.get(config.api.lists.b))
- // .then(json => {
- // newData[1] = json;
- this.setState({ data: newData });
- })
- .catch(error => {
- console.error(error); // eslint-disable-line
- });
- }
- // Update state depending on chart mode and current question
- toNextStep () {
- const nextQuestion = this.state.currentQuestion < this.state.questions.length - 1;
- const nextStep = this.state.currentStep < this.state.questions[this.state.currentQuestion].texts.length - 1;
- if (this.state.chartMode === 'interaction') { // If in interaction mode, go to presentation mode
- if (!this.props.isOffline) {
- api.post(
- this.state.currentQuestion === 0 ? config.api.creates.a : config.api.creates.b,
- {
- userId: this.state.userId,
- kontext: this.state.questions[this.state.currentQuestion].yKeys[this.state.currentStep],
- punkte: this.state.interactionData
- },
- this.state.token
- )
- .then(() => {
- this.setState({ chartMode: 'presentation' });
- });
- } else {
- this.setState({ chartMode: 'presentation' });
- }
- } else if (this.state.chartMode === 'presentation' && !this.props.isOffline) { // If 'online' and in presentation mode, go to comparison mode
- api.get(
- this.state.currentQuestion === 0 ? config.api.proportions.a : config.api.proportions.b,
- { kontext: this.state.questions[this.state.currentQuestion].yKeys[this.state.currentStep] })
- .then(json => {
- this.setState({ chartMode: 'comparison', comparisonData: json });
- });
- } else if (nextStep) {
- this.setState({
- chartMode: 'interaction',
- currentStep: this.state.currentStep + 1,
- interactionData: [],
- comparisonData: []
- });
- } else if (nextQuestion) {
- this.setState({
- chartMode: 'interaction',
- currentQuestion: this.state.currentQuestion + 1,
- currentStep: 0,
- interactionData: [],
- comparisonData: []
- });
- } else {
- // Go to finalscreen
- this.setState({ route: 'finalscreen' });
- }
- }
- // LIFECYCLE
- componentDidMount () {
- this.setup();
- }
- // RENDER
- render () {
- let outputContent;
- switch (this.state.route) {
- case 'question':
- outputContent = <ChartScreen
- {...content}
- data={this.state.data}
- comparisonData={this.state.comparisonData}
- interactionData={this.state.mode === 'interaction' ? [] : this.state.interactionData}
- mode={this.state.chartMode}
- route={this.state.route}
- questions={this.state.questions}
- currentQuestion={this.state.currentQuestion}
- currentStep={this.state.currentStep}
- setData={this.setData}
- toNextStep={this.toNextStep} />;
- break;
- case 'finalscreen':
- outputContent = <FinalScreen
- {...content}
- navigate={this.navigate}
- isFetching={this.state.isFetching} />;
- break;
- case 'titlescreen':
- default:
- outputContent = <TitleScreen
- {...content}
- navigate={ this.navigate }
- navigateTo='question'
- isFetching={this.state.isFetching} />;
- break;
- }
- return outputContent;
- }
- }
|