/* global gettext */ import React from 'react'; import isFunction from 'lodash/isFunction'; const Page = ({ children }) => children; const Header = () => null; const Closer = () => null; const ErrorPage = () => null; export default class Wizard extends React.Component { constructor(props) { super(props); this.findSubComponentByType = this.findSubComponentByType.bind(this); this.handleNext = this.handleNext.bind(this); this.state = { currentPage: 1, totalPages: 0, pages: [], wizardContext: {}, } this.wizardComplete = this.wizardComplete.bind(this); } componentDidMount() { const pages = this.findSubComponentByType(Wizard.Page.name); const totalPages = pages.length; const wizardContext = this.props.wizardContext; const closer = this.findSubComponentByType(Wizard.Closer.name)[0]; pages.push(closer); this.setState({ pages, totalPages, wizardContext }); } handleNext() { if (this.state.currentPage < this.props.children.length) { this.setState(prevState => ({ currentPage: prevState.currentPage + 1 })) } } findSubComponentByType(type) { return React.Children.toArray(this.props.children).filter(child => child.type.name === type) } // this needs to handle the case of no provided header renderHeader() { const header = this.findSubComponentByType(Wizard.Header.name)[0]; return header.props.children({ currentPage: this.state.currentPage, totalPages: this.state.totalPages }) } renderPage() { if (this.state.totalPages) { const page = this.state.pages[this.state.currentPage - 1]; if (page.type.name === Wizard.Closer.name) { return page.props.children; } if (isFunction(page.props.children)) { return page.props.children({ wizardConsumer: this.props.wizardContext }); } else { return page.props.children; } } return null; } // this needs to handle the case of no provided errorPage renderError() { const errorPage = this.findSubComponentByType(Wizard.ErrorPage.name)[0]; return (
{errorPage.props.children}
) } /** * Utility method that helps determine if the learner is on the final page of the modal. */ onFinalPage() { return this.state.pages.length === this.state.currentPage; } /** * Utility method for closing the modal and returning the learner back to the Course Dashboard. * If a learner is on the final page of the modal, meaning they have answered all of the * questions, clicking the "Return to my dashboard" button will also dismiss the CTA from the * course dashboard. */ async wizardComplete() { if (this.onFinalPage()) { this.props.dismissBanner(); } this.props.onWizardComplete(); } render() { const finalPage = this.onFinalPage(); if (this.props.error) { return this.renderError(); } return (
{this.state.totalPages >= this.state.currentPage && this.renderHeader()}
{this.renderPage()}
); } } Wizard.Page = Page; Wizard.Header = Header; Wizard.Closer = Closer; Wizard.ErrorPage = ErrorPage;