import React from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import * as actions from 'loot-core/src/client/actions';
import BudgetCategories from './tutorial/BudgetCategories';
import BudgetInitial from './tutorial/BudgetInitial';
import BudgetNewIncome from './tutorial/BudgetNewIncome';
import BudgetNextMonth from './tutorial/BudgetNextMonth';
import BudgetSummary from './tutorial/BudgetSummary';
import CategoryBalance from './tutorial/CategoryBalance';
import Final from './tutorial/Final';
import Intro from './tutorial/Intro';
import Overspending from './tutorial/Overspending';
import TransactionAdd from './tutorial/TransactionAdd';
import TransactionEnter from './tutorial/TransactionEnter';
function generatePath(innerRect, outerRect) {
const i = innerRect;
const o = outerRect;
// prettier-ignore
return `
M0,0 ${o.width},0 ${o.width},${o.height} L0,${o.height} L0,0 Z
M${i.left},${i.top} L${i.left+i.width},${i.top} L${i.left+i.width},${i.top+i.height} L${i.left},${i.top+i.height} L${i.left},${i.top} Z
`;
}
function expandRect({ top, left, width, height }, padding) {
if (typeof padding === 'number') {
return {
top: top - padding,
left: left - padding,
width: width + padding * 2,
height: height + padding * 2
};
} else if (padding) {
return {
top: top - (padding.top || 0),
left: left - (padding.left || 0),
width: width + (padding.right || 0) + (padding.left || 0),
height: height + (padding.bottom || 0) + (padding.top || 0)
};
}
return { top, left, width, height };
}
function withinWindow(rect) {
return {
top: rect.top,
left: rect.left,
width: Math.min(rect.left + rect.width, window.innerWidth) - rect.left,
height: Math.min(rect.top + rect.height, window.innerHeight) - rect.top
};
}
class MeasureNodes extends React.Component {
state = { measurements: null };
componentDidMount() {
window.addEventListener('resize', () => {
setTimeout(() => this.updateMeasurements(true), 0);
});
this.updateMeasurements();
}
componentDidUpdate(prevProps) {
if (prevProps.nodes !== this.props.nodes) {
this.updateMeasurements();
}
}
updateMeasurements() {
this.setState({
measurements: this.props.nodes.map(node => node.getBoundingClientRect())
});
}
render() {
const { children } = this.props;
const { measurements } = this.state;
return measurements ? children(...measurements) : null;
}
}
class Tutorial extends React.Component {
state = { highlightRect: null, windowRect: null };
static contextTypes = {
getTutorialNode: PropTypes.func,
endTutorial: PropTypes.func
};
onClose = didQuitEarly => {
// The difference between these is `endTutorial` permanently
// disable the tutorial. If the user walked all the way through
// it, never show it to them again. Otherwise they will see if
// again if they create a new budget.
if (didQuitEarly) {
this.props.closeTutorial();
} else {
this.props.endTutorial();
}
};
getContent(stage, targetRect, navigationProps) {
switch (stage) {
case 'budget-summary':
return (